100 #define HTP_MAX_MESSAGES 512
106 static uint64_t htp_state_memuse = 0;
107 static uint64_t htp_state_memcnt = 0;
117 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST",
119 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE",
121 {
"INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST",
123 {
"INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE",
125 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST",
127 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE",
130 {
"UNABLE_TO_MATCH_RESPONSE_TO_REQUEST",
145 {
"REQUEST_SERVER_PORT_TCP_PORT_MISMATCH",
159 {
"RESPONSE_ABNORMAL_TRANSFER_ENCODING",
203 static int HTTPGetFrameIdByName(
const char *frame_name)
212 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
218 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
219 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
220 static uint64_t HTPStateGetTxCnt(
void *alstate);
222 static void HTPParserRegisterTests(
void);
225 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
227 uint64_t
id = HTPStateGetTxCnt(s);
232 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
245 static const char *HTPLookupPersonalityString(
int p)
247 #define CASE_HTP_PERSONALITY_STRING(p) \
248 case HTP_SERVER_ ## p: return #p
251 CASE_HTP_PERSONALITY_STRING(MINIMAL);
252 CASE_HTP_PERSONALITY_STRING(GENERIC);
253 CASE_HTP_PERSONALITY_STRING(IDS);
254 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
255 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
256 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
257 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
258 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
259 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
260 CASE_HTP_PERSONALITY_STRING(APACHE_2);
274 static int HTPLookupPersonality(
const char *
str)
276 #define IF_HTP_PERSONALITY_NUM(p) \
277 if (strcasecmp(#p, str) == 0) return HTP_SERVER_ ## 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.",
301 return HTP_SERVER_APACHE_2;
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);
457 tx->request_progress == HTP_REQUEST_COMPLETE &&
458 tx->response_progress == HTP_RESPONSE_COMPLETE)))
460 tx->request_progress = HTP_REQUEST_COMPLETE;
461 tx->response_progress = HTP_RESPONSE_COMPLETE;
511 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
516 if (
flags & STREAM_TOCLIENT) {
526 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
543 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
544 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
546 uint32_t chunk_len = 0;
548 (content_len_so_far < (uint64_t)body_limit) &&
549 (content_len_so_far + (uint64_t)data_len) > body_limit)
551 chunk_len = (uint32_t)(body_limit - content_len_so_far);
553 (content_len_so_far < (uint64_t)stream_depth) &&
554 (content_len_so_far + (uint64_t)data_len) > stream_depth)
556 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
559 return (chunk_len == 0 ? data_len : chunk_len);
606 {
"Request line: URI contains non-compliant delimiter",
608 {
"Request line: non-compliant delimiter between Method and URI",
617 {
"Transfer-encoding has abnormal chunked value",
619 {
"Chunked transfer-encoding on HTTP/0.9 or HTTP/1.0",
622 {
"Invalid response line: invalid response status",
628 {
"Ambiguous response C-L value",
634 #define HTP_ERROR_MAX (sizeof(htp_errors) / sizeof(htp_errors[0]))
635 #define HTP_WARNING_MAX (sizeof(htp_warnings) / sizeof(htp_warnings[0]))
646 static uint8_t HTPHandleWarningGetId(
const char *
msg)
670 static uint8_t HTPHandleErrorGetId(
const char *
msg)
694 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
696 if (s == NULL || s->
conn == NULL ||
697 s->
conn->messages == NULL) {
701 size_t size = htp_list_size(s->
conn->messages);
716 htp_log_t *log = htp_list_get(s->
conn->messages,
msg);
721 htp_tx_t *tx = log->tx;
727 uint8_t
id = HTPHandleErrorGetId(log->msg);
729 id = HTPHandleWarningGetId(log->msg);
735 HTPSetEvent(s, htud, dir,
id);
742 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s, htp_tx_t *tx)
745 BUG_ON(s == NULL || tx == NULL);
747 if (tx->flags & ( HTP_REQUEST_INVALID_T_E|HTP_REQUEST_INVALID_C_L|
748 HTP_HOST_MISSING|HTP_HOST_AMBIGUOUS|HTP_HOSTU_INVALID|
755 if (tx->flags & HTP_REQUEST_INVALID_T_E)
756 HTPSetEvent(s, htud, STREAM_TOSERVER,
758 if (tx->flags & HTP_REQUEST_INVALID_C_L)
759 HTPSetEvent(s, htud, STREAM_TOSERVER,
761 if (tx->flags & HTP_HOST_MISSING)
762 HTPSetEvent(s, htud, STREAM_TOSERVER,
764 if (tx->flags & HTP_HOST_AMBIGUOUS)
765 HTPSetEvent(s, htud, STREAM_TOSERVER,
767 if (tx->flags & HTP_HOSTU_INVALID)
768 HTPSetEvent(s, htud, STREAM_TOSERVER,
770 if (tx->flags & HTP_HOSTH_INVALID)
771 HTPSetEvent(s, htud, STREAM_TOSERVER,
774 if (tx->request_auth_type == HTP_AUTH_UNRECOGNIZED) {
778 HTPSetEvent(s, htud, STREAM_TOSERVER,
781 if (tx->is_protocol_0_9 && tx->request_method_number == HTP_M_UNKNOWN &&
782 (tx->request_protocol_number == HTP_PROTOCOL_INVALID ||
783 tx->request_protocol_number == HTP_PROTOCOL_UNKNOWN)) {
787 HTPSetEvent(s, htud, STREAM_TOSERVER,
798 htp_cfg_t *htp = cfglist.
cfg;
799 void *user_data = NULL;
814 if (user_data != NULL) {
815 htp_cfg_rec = user_data;
816 htp = htp_cfg_rec->
cfg;
819 SCLogDebug(
"Using default HTP config: %p", htp);
823 #ifdef DEBUG_VALIDATION
830 hstate->
connp = htp_connp_create(htp);
831 if (hstate->
connp == NULL) {
835 hstate->
conn = htp_connp_get_connection(hstate->
connp);
837 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
838 hstate->
cfg = htp_cfg_rec;
843 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
865 StreamSlice stream_slice,
void *local_data)
875 if (NULL == hstate->
conn) {
876 if (Setup(f, hstate) != 0) {
881 hstate->
slice = &stream_slice;
883 const uint8_t *input = StreamSliceGetData(&stream_slice);
884 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
889 const int r = htp_connp_req_data(hstate->
connp, &
ts, input, input_len);
891 case HTP_STREAM_ERROR:
897 HTPHandleError(hstate, STREAM_TOSERVER);
904 htp_connp_req_close(hstate->
connp, &
ts);
906 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
910 hstate->
slice = NULL;
932 StreamSlice stream_slice,
void *local_data)
938 const uint8_t *input = StreamSliceGetData(&stream_slice);
939 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
945 if (NULL == hstate->
conn) {
946 if (Setup(f, hstate) != 0) {
951 hstate->
slice = &stream_slice;
955 uint32_t consumed = 0;
957 const int r = htp_connp_res_data(hstate->
connp, &
ts, input, input_len);
959 case HTP_STREAM_ERROR:
962 case HTP_STREAM_TUNNEL:
963 tx = htp_connp_get_out_tx(hstate->
connp);
964 if (tx != NULL && tx->response_status_number == 101) {
966 (htp_header_t *)htp_table_get_c(tx->response_headers,
"Upgrade");
971 if (tx->request_port_number != -1) {
972 dp = (uint16_t)tx->request_port_number;
974 consumed = (uint32_t)htp_connp_res_data_consumed(hstate->
connp);
975 if (bstr_cmp_c(h->value,
"h2c") == 0) {
980 hstate->
slice = NULL;
982 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
987 if (consumed > 0 && consumed < input_len) {
991 }
else if (bstr_cmp_c_nocase(h->value,
"WebSocket") == 0) {
996 hstate->
slice = NULL;
998 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
1003 if (consumed > 0 && consumed < input_len) {
1013 HTPHandleError(hstate, STREAM_TOCLIENT);
1020 htp_connp_close(hstate->
connp, &
ts);
1025 hstate->
slice = NULL;
1036 static int HTTPParseContentDispositionHeader(uint8_t *name,
size_t name_len,
1037 uint8_t *data,
size_t len, uint8_t **retptr,
size_t *retlen)
1040 printf(
"DATA START: \n");
1042 printf(
"DATA END: \n");
1047 for (x = 0; x <
len; x++) {
1048 if (!(isspace(data[x])))
1055 uint8_t *line = data+x;
1056 size_t line_len =
len-x;
1059 printf(
"LINE START: \n");
1061 printf(
"LINE END: \n");
1063 for (x = 0 ; x < line_len; x++) {
1065 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
1069 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
1070 uint8_t *token = line +
offset;
1071 size_t token_len = x -
offset;
1073 if ((x + 1) == line_len) {
1084 printf(
"TOKEN START: \n");
1086 printf(
"TOKEN END: \n");
1088 if (token_len > name_len) {
1089 if (name == NULL || SCMemcmpLowercase(name, token, name_len) == 0) {
1090 uint8_t *value = token + name_len;
1091 size_t value_len = token_len - name_len;
1093 if (value[0] ==
'\"') {
1097 if (value[value_len-1] ==
'\"') {
1101 printf(
"VALUE START: \n");
1103 printf(
"VALUE END: \n");
1106 *retlen = value_len;
1130 static int HtpRequestBodySetupMultipart(htp_tx_t *tx,
HtpTxUserData *htud)
1132 htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->request_headers,
1134 if (h != NULL && bstr_len(h->value) > 0) {
1135 htud->
mime_state = SCMimeStateInit(bstr_ptr(h->value), (uint32_t)bstr_len(h->value));
1152 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1155 chunks_buffer, chunks_buffer_len,
1159 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1162 if (tx && tx->
tx_data.de_state) {
1163 if (dir == STREAM_TOSERVER) {
1164 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1166 }
else if (STREAM_TOCLIENT) {
1167 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1174 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1177 printf(
"CHUNK START: \n");
1179 printf(
"CHUNK END: \n");
1185 STREAM_TOSERVER) >= HTP_REQUEST_COMPLETE);
1187 const uint8_t *cur_buf = chunks_buffer;
1188 uint32_t cur_buf_len = chunks_buffer_len;
1204 const uint8_t *filename = NULL;
1205 uint16_t filename_len = 0;
1208 while (cur_buf_len > 0) {
1209 MimeParserResult r =
1210 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1214 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1218 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1229 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1230 if (filename_len > 0) {
1234 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1237 }
else if (result == -2) {
1240 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1248 }
else if (result == -2) {
1256 uint32_t lastsize = consumed;
1257 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1259 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1263 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1268 cur_buf += consumed;
1269 cur_buf_len -= consumed;
1281 htp_tx_t *tx, uint8_t *data, uint32_t data_len)
1288 uint8_t *filename = NULL;
1289 size_t filename_len = 0;
1292 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1293 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1294 filename_len = bstr_len(tx->parsed_uri->path);
1297 if (filename != NULL) {
1303 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1307 }
else if (result == -2) {
1310 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1324 }
else if (result == -2) {
1337 htp_tx_t *tx, uint8_t *data, uint32_t data_len)
1350 uint8_t *filename = NULL;
1351 size_t filename_len = 0;
1354 htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->response_headers,
1355 "Content-Disposition");
1356 if (h != NULL && bstr_len(h->value) > 0) {
1358 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1359 (uint8_t *) bstr_ptr(h->value), bstr_len(h->value), &filename, &filename_len);
1363 if (filename == NULL) {
1365 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1366 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1367 filename_len = bstr_len(tx->parsed_uri->path);
1371 if (filename != NULL) {
1373 htp_header_t *h_content_range = htp_table_get_c(tx->response_headers,
"content-range");
1379 if (h_content_range != NULL) {
1381 data_len, tx, h_content_range->value, htud);
1383 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1389 }
else if (result == -2) {
1392 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1405 }
else if (result == -2) {
1423 static int HTPCallbackRequestBodyData(htp_tx_data_t *d)
1434 printf(
"HTPBODY START: \n");
1436 printf(
"HTPBODY END: \n");
1439 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1440 if (hstate == NULL) {
1444 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1445 "%"PRIu32
"", hstate, d, d->data, (uint32_t)d->len);
1448 if (tx_ud == NULL) {
1456 if (d->tx->request_method_number == HTP_M_POST) {
1458 int r = HtpRequestBodySetupMultipart(d->tx, tx_ud);
1461 }
else if (r == 0) {
1465 }
else if (d->tx->request_method_number == HTP_M_PUT) {
1488 const uint8_t *chunks_buffer = NULL;
1489 uint32_t chunks_buffer_len = 0;
1497 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1498 if (chunks_buffer == NULL) {
1502 printf(
"REASSCHUNK START: \n");
1504 printf(
"REASSCHUNK END: \n");
1507 HtpRequestBodyHandleMultipart(hstate, tx_ud, d->tx, chunks_buffer, chunks_buffer_len,
1508 (d->data == NULL && d->len == 0));
1512 HtpRequestBodyHandlePOSTorPUT(hstate, tx_ud, d->tx, (uint8_t *)d->data,
len);
1517 SCLogDebug(
"closing file that was being stored");
1524 if (hstate->
conn != NULL) {
1525 SCLogDebug(
"checking body size %"PRIu64
" against inspect limit %u (cur %"PRIu64
", last %"PRIu64
")",
1539 const uint32_t data_size = (uint32_t)(
1560 static int HTPCallbackResponseBodyData(htp_tx_data_t *d)
1570 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1571 if (hstate == NULL) {
1575 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1576 "%"PRIu32
"", hstate, d, d->data, (uint32_t)d->len);
1579 if (tx_ud == NULL) {
1605 HtpResponseBodyHandle(hstate, tx_ud, d->tx, (uint8_t *)d->data,
len);
1608 SCLogDebug(
"closing file that was being stored");
1614 if (hstate->
conn != NULL) {
1615 SCLogDebug(
"checking body size %"PRIu64
" against inspect limit %u (cur %"PRIu64
", last %"PRIu64
")",
1628 const uint32_t data_size = (uint32_t)((uint64_t)hstate->
conn->out_data_counter -
1652 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1653 htp_state_memcnt, htp_state_memuse);
1673 htp_config_destroy(cfglist.
cfg);
1674 while (nextrec != NULL) {
1676 nextrec = nextrec->
next;
1678 htp_config_destroy(htprec->
cfg);
1684 static int HTPCallbackRequestHasTrailer(htp_tx_t *tx)
1693 static int HTPCallbackResponseHasTrailer(htp_tx_t *tx)
1706 static int HTPCallbackRequestStart(htp_tx_t *tx)
1708 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1709 if (hstate == NULL) {
1713 uint64_t consumed = hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1714 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1715 (uint64_t)hstate->
conn->in_data_counter);
1732 if (tx_ud == NULL) {
1737 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1738 htp_tx_set_user_data(tx, tx_ud);
1747 static int HTPCallbackResponseStart(htp_tx_t *tx)
1749 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1750 if (hstate == NULL) {
1754 uint64_t consumed = hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1755 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1756 (uint64_t)hstate->
conn->out_data_counter);
1771 if (tx_ud == NULL) {
1778 htp_tx_set_user_data(tx, tx_ud);
1789 static int HTPCallbackRequestComplete(htp_tx_t *tx)
1797 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1798 if (hstate == NULL) {
1802 const uint64_t abs_right_edge =
1803 hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1811 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1813 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1815 frame->
len = (int64_t)request_size;
1821 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1826 HTPErrorCheckTxRequestFlags(hstate, tx);
1831 SCLogDebug(
"closing file that was being stored");
1834 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1836 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1854 static int HTPCallbackResponseComplete(htp_tx_t *tx)
1858 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1859 if (hstate == NULL) {
1866 const uint64_t abs_right_edge =
1867 hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1874 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1876 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1878 frame->
len = (int64_t)response_size;
1886 SCLogDebug(
"closing file that was being stored");
1897 if (tx->request_method_number == HTP_M_CONNECT) {
1900 if ((tx->response_status_number >= 200) &&
1901 (tx->response_status_number < 300) &&
1904 if (tx->request_port_number != -1) {
1905 dp = (uint16_t)tx->request_port_number;
1912 tx->request_progress = HTP_REQUEST_COMPLETE;
1913 tx->response_progress = HTP_RESPONSE_COMPLETE;
1921 static int HTPCallbackRequestLine(htp_tx_t *tx)
1924 bstr *request_uri_normalized;
1925 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1929 if (request_uri_normalized == NULL)
1932 tx_ud = htp_tx_get_user_data(tx);
1934 bstr_free(request_uri_normalized);
1942 HTPErrorCheckTxRequestFlags(hstate, tx);
1947 static int HTPCallbackDoubleDecodeUriPart(htp_tx_t *tx, bstr *part)
1953 size_t prevlen = bstr_len(part);
1954 htp_status_t res = htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, part, &
flags);
1956 if (res == HTP_OK && prevlen > bstr_len(part)) {
1960 HtpState *s = htp_connp_get_user_data(tx->connp);
1963 HTPSetEvent(s, htud, STREAM_TOSERVER,
1970 static int HTPCallbackDoubleDecodeQuery(htp_tx_t *tx)
1972 if (tx->parsed_uri == NULL)
1975 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->query);
1978 static int HTPCallbackDoubleDecodePath(htp_tx_t *tx)
1980 if (tx->parsed_uri == NULL)
1983 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->path);
1986 static int HTPCallbackRequestHeaderData(htp_tx_data_t *tx_data)
1989 if (tx_data->len == 0 || tx_data->tx == NULL)
1993 if (tx_ud == NULL) {
2005 tx_data->data, tx_data->len);
2008 if (tx_data->tx && tx_data->tx->flags) {
2009 HtpState *hstate = htp_connp_get_user_data(tx_data->tx->connp);
2010 HTPErrorCheckTxRequestFlags(hstate, tx_data->tx);
2015 static int HTPCallbackResponseHeaderData(htp_tx_data_t *tx_data)
2018 if (tx_data->len == 0 || tx_data->tx == NULL)
2022 if (tx_ud == NULL) {
2034 tx_data->data, tx_data->len);
2043 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
2060 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2061 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2062 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2063 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2065 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
2066 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
2068 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
2069 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
2071 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
2072 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
2074 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
2075 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
2077 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
2078 #ifdef HAVE_HTP_CONFIG_SET_ALLOW_SPACE_URI
2079 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
2083 htp_config_set_plusspace_decode(cfg_prec->
cfg, HTP_DECODER_URLENCODED, 0);
2085 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
2086 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2090 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2091 htp_config_set_lzma_memlimit(cfg_prec->
cfg,
2094 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2095 htp_config_set_compression_bomb_limit(cfg_prec->
cfg,
2098 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2101 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2102 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
2103 htp_config_set_max_tx(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_MAX_TX_LIMIT);
2118 static int RandomGetWrap(
void)
2124 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
2126 return r % RAND_MAX;
2135 static void HTPConfigSetDefaultsPhase2(
const char *name,
HTPCfgRec *cfg_prec)
2141 long int r = RandomGetWrap();
2143 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2145 r = RandomGetWrap();
2147 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2148 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
2149 " %u and 'request-body-inspect-window' set to %u after"
2153 r = RandomGetWrap();
2155 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2157 r = RandomGetWrap();
2159 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2161 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2162 " %u and 'response-body-inspect-window' set to %u after"
2167 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2173 if (cfg_prec == NULL || s == NULL || tree == NULL)
2181 if (strcasecmp(
"address", p->
name) == 0) {
2189 if (strchr(pval->
val,
':') != NULL) {
2190 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2194 "add ipv6 server %s, ignoring",
2198 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2202 "to add ipv4 server %s, ignoring",
2208 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2210 int personality = HTPLookupPersonality(p->
val);
2214 if (personality >= 0) {
2217 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) == HTP_ERROR){
2219 "personality \"%s\", ignoring",
2223 HTPLookupPersonalityString(personality));
2229 htp_config_set_convert_lowercase(cfg_prec->
cfg, HTP_DECODER_URL_PATH, 0);
2237 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2238 strcasecmp(
"request_body_limit", p->
name) == 0) {
2240 SCLogError(
"Error parsing request-body-limit "
2241 "from conf file - %s. Killing engine",
2246 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2248 SCLogError(
"Error parsing response-body-limit "
2249 "from conf file - %s. Killing engine",
2254 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2256 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2257 "from conf file - %s. Killing engine",
2262 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2264 SCLogError(
"Error parsing request-body-inspect-window "
2265 "from conf file - %s. Killing engine",
2270 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2272 htp_config_register_request_line(cfg_prec->
cfg,
2273 HTPCallbackDoubleDecodeQuery);
2276 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2278 htp_config_register_request_line(cfg_prec->
cfg,
2279 HTPCallbackDoubleDecodePath);
2282 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2284 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2285 "from conf file - %s. Killing engine",
2290 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2292 SCLogError(
"Error parsing response-body-inspect-window "
2293 "from conf file - %s. Killing engine",
2298 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2301 SCLogError(
"Error parsing response-body-inspect-window "
2302 "from conf file - %s. Killing engine",
2306 #ifdef HAVE_HTP_CONFIG_SET_RESPONSE_DECOMPRESSION_LAYER_LIMIT
2307 htp_config_set_response_decompression_layer_limit(cfg_prec->
cfg, value);
2309 SCLogWarning(
"can't set response-body-decompress-layer-limit "
2310 "to %u, libhtp version too old",
2313 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2314 htp_config_set_backslash_convert_slashes(cfg_prec->
cfg,
2315 HTP_DECODER_URL_PATH,
2317 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2318 if (strlen(p->
val) == 1) {
2319 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg,
2320 HTP_DECODER_URL_PATH,
2324 "for libhtp param path-bestfit-replacement-char");
2326 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2327 htp_config_set_convert_lowercase(cfg_prec->
cfg,
2328 HTP_DECODER_URL_PATH,
2330 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2331 htp_config_set_nul_encoded_terminates(cfg_prec->
cfg,
2332 HTP_DECODER_URL_PATH,
2334 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2335 htp_config_set_nul_raw_terminates(cfg_prec->
cfg,
2336 HTP_DECODER_URL_PATH,
2338 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2339 htp_config_set_path_separators_compress(cfg_prec->
cfg,
2340 HTP_DECODER_URL_PATH,
2342 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2343 htp_config_set_path_separators_decode(cfg_prec->
cfg,
2344 HTP_DECODER_URL_PATH,
2346 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2347 htp_config_set_u_encoding_decode(cfg_prec->
cfg,
2348 HTP_DECODER_URL_PATH,
2350 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2351 enum htp_url_encoding_handling_t handling;
2352 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2353 handling = HTP_URL_DECODE_PRESERVE_PERCENT;
2354 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2355 handling = HTP_URL_DECODE_REMOVE_PERCENT;
2356 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2357 handling = HTP_URL_DECODE_PROCESS_INVALID;
2360 "for libhtp param path-url-encoding-invalid-handling");
2363 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg,
2364 HTP_DECODER_URL_PATH,
2366 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2367 htp_config_set_utf8_convert_bestfit(cfg_prec->
cfg,
2368 HTP_DECODER_URL_PATH,
2370 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2374 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2375 htp_config_set_plusspace_decode(cfg_prec->
cfg,
2376 HTP_DECODER_URLENCODED,
2378 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2382 "from conf file - %s. Killing engine",
2388 "from conf file cannot be 0. Killing engine");
2391 htp_config_set_field_limits(cfg_prec->
cfg,
2394 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2395 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2398 FatalError(
"failed to parse 'lzma-memlimit' "
2399 "from conf file - %s.",
2404 "from conf file cannot be 0.");
2407 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2408 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2410 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2411 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2413 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2418 "from conf file - %s.",
2421 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2422 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2425 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2426 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2429 FatalError(
"failed to parse 'compression-bomb-limit' "
2430 "from conf file - %s.",
2435 "from conf file cannot be 0.");
2438 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2439 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2441 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2442 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2446 FatalError(
"failed to parse 'decompression-time-limit' "
2447 "from conf file - %s.",
2450 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2451 htp_config_set_compression_time_limit(cfg_prec->
cfg, (
size_t)limit);
2453 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2454 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2458 "from conf file - %s.",
2462 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2463 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2465 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2469 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2472 (
const char *)p->
val, 0, 100) < 0) {
2474 "-inspection-range setting from conf file - \"%s\"."
2475 " It should be a valid integer less than or equal to 100."
2481 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2487 if (strcmp(
"auto", p->
val) != 0) {
2496 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2500 if (strcasecmp(
"enabled", pval->
name) == 0) {
2508 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2509 if (strcasecmp(
"no", pval->
val) == 0) {
2511 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2513 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2515 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2519 "swf-decompression.type: %s - "
2524 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2526 SCLogError(
"Error parsing swf-decompression.compression-depth "
2527 "from conf file - %s. Killing engine",
2531 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2533 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2534 "from conf file - %s. Killing engine",
2544 "default config: %s",
2554 cfglist.
next = NULL;
2561 if (NULL == cfgtree)
2565 cfglist.
cfg = htp_config_create();
2566 if (NULL == cfglist.
cfg) {
2567 FatalError(
"Failed to create HTP default config");
2570 HTPConfigSetDefaultsPhase1(&cfglist);
2571 if (
ConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2572 HTPConfigParseParameters(&cfglist,
ConfGetNode(
"libhtp.default-config"),
2575 HTPConfigParseParameters(&cfglist,
ConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), cfgtree);
2577 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2583 if (server_config == NULL) {
2584 server_config =
ConfGetNode(
"libhtp.server-config");
2585 if (server_config == NULL) {
2586 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2590 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2609 cfglist.
next = htprec;
2612 cfglist.
next->
cfg = htp_config_create();
2613 if (NULL == cfglist.
next->
cfg) {
2614 FatalError(
"Failed to create HTP server config");
2617 HTPConfigSetDefaultsPhase1(htprec);
2618 HTPConfigParseParameters(htprec, s, cfgtree);
2619 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2629 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2640 static AppLayerGetFileState HTPGetTxFiles(
void *txv, uint8_t direction)
2642 AppLayerGetFileState files = { .fc = NULL, .cfg = &
htp_sbcfg };
2643 htp_tx_t *tx = (htp_tx_t *)txv;
2646 if (direction & STREAM_TOCLIENT) {
2655 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2657 if (direction & STREAM_TOSERVER)
2658 return ((htp_tx_t *)tx)->request_progress;
2660 return ((htp_tx_t *)tx)->response_progress;
2663 static uint64_t HTPStateGetTxCnt(
void *alstate)
2667 if (http_state != NULL && http_state->
conn != NULL) {
2668 const int64_t size = (int64_t)htp_list_size(http_state->
conn->transactions);
2672 return (uint64_t)size + http_state->
tx_freed;
2678 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2682 if (http_state != NULL && http_state->
conn != NULL && tx_id >= http_state->
tx_freed)
2683 return htp_list_get(http_state->
conn->transactions, tx_id - http_state->
tx_freed);
2692 if (http_state != NULL && http_state->
conn != NULL) {
2693 size_t txid = HTPStateGetTxCnt(http_state);
2695 return htp_list_get(http_state->
conn->transactions, txid - http_state->
tx_freed - 1);
2701 static int HTPStateGetEventInfo(
const char *event_name,
2702 int *event_id, AppLayerEventType *event_type)
2705 if (*event_id == -1) {
2707 "http's enum map table.",
2713 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2718 static int HTPStateGetEventInfoById(
int event_id,
const char **event_name,
2719 AppLayerEventType *event_type)
2722 if (*event_name == NULL) {
2724 "http's enum map table.",
2730 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2737 htp_tx_t *tx = (htp_tx_t *)vtx;
2745 static AppLayerStateData *HTPGetStateData(
void *vstate)
2751 static int HTPRegisterPatternsForProtocolDetection(
void)
2753 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2754 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2755 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2756 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2757 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2758 const char *spacings[] = {
"|20|",
"|09|", NULL };
2759 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2764 int register_result;
2765 char method_buffer[32] =
"";
2768 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2769 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2772 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2779 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2780 if (register_result < 0) {
2787 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2789 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2791 if (register_result < 0) {
2807 const char *proto_name =
"http";
2812 if (HTPRegisterPatternsForProtocolDetection() < 0)
2815 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2830 ALPROTO_HTTP1, HTP_REQUEST_COMPLETE, HTP_RESPONSE_COMPLETE);
2842 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2844 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2850 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2853 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2857 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2873 cfglist_backup = cfglist;
2878 cfglist = cfglist_backup;
2883 static int HTPParserTest01(
void)
2885 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2887 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2890 memset(&ssn, 0,
sizeof(ssn));
2898 f->
proto = IPPROTO_TCP;
2904 for (u = 0; u < httplen1; u++) {
2908 flags = STREAM_TOSERVER|STREAM_START;
2909 else if (u == (httplen1 - 1))
2910 flags = STREAM_TOSERVER|STREAM_EOF;
2912 flags = STREAM_TOSERVER;
2921 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2924 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
2927 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
2928 FAIL_IF(tx->request_method_number != HTP_M_POST);
2929 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
2938 static int HTPParserTest01b(
void)
2940 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2942 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2945 memset(&ssn, 0,
sizeof(ssn));
2953 f->
proto = IPPROTO_TCP;
2958 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2965 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2968 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
2971 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
2972 FAIL_IF(tx->request_method_number != HTP_M_POST);
2973 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
2982 static int HTPParserTest01c(
void)
2984 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2986 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2989 memset(&ssn, 0,
sizeof(ssn));
2997 f->
proto = IPPROTO_TCP;
3003 for (u = 0; u < httplen1; u++) {
3007 flags = STREAM_TOSERVER|STREAM_START;
3008 else if (u == (httplen1 - 1))
3009 flags = STREAM_TOSERVER|STREAM_EOF;
3011 flags = STREAM_TOSERVER;
3020 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3023 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3026 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
3027 FAIL_IF(tx->request_method_number != HTP_M_POST);
3028 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
3038 static int HTPParserTest01a(
void)
3042 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3044 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3050 memset(&ssn, 0,
sizeof(ssn));
3052 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3056 f->
proto = IPPROTO_TCP;
3062 for (u = 0; u < httplen1; u++) {
3066 flags = STREAM_TOSERVER|STREAM_START;
3067 else if (u == (httplen1 - 1))
3068 flags = STREAM_TOSERVER|STREAM_EOF;
3070 flags = STREAM_TOSERVER;
3074 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3081 if (htp_state == NULL) {
3082 printf(
"no http state: ");
3086 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3087 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3088 if (strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0")
3089 || tx->request_method_number != HTP_M_POST ||
3090 tx->request_protocol_number != HTP_PROTOCOL_1_0)
3092 printf(
"expected header value: Victor/1.0 and got %s: and expected"
3093 " method: POST and got %s, expected protocol number HTTP/1.0"
3094 " and got: %s \n", bstr_util_strdup_to_c(h->value),
3095 bstr_util_strdup_to_c(tx->request_method),
3096 bstr_util_strdup_to_c(tx->request_protocol));
3109 static int HTPParserTest02(
void)
3113 uint8_t httpbuf1[] =
"POST";
3114 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3119 memset(&ssn, 0,
sizeof(ssn));
3121 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3125 f->
proto = IPPROTO_TCP;
3131 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3133 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3138 if (http_state == NULL) {
3139 printf(
"no http state: ");
3143 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3145 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3149 char *method = bstr_util_strdup_to_c(tx->request_method);
3152 FAIL_IF(strcmp(method,
"POST") != 0);
3166 static int HTPParserTest03(
void)
3170 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
3171 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3177 memset(&ssn, 0,
sizeof(ssn));
3179 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3183 f->
proto = IPPROTO_TCP;
3189 for (u = 0; u < httplen1; u++) {
3192 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3193 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3194 else flags = STREAM_TOSERVER;
3198 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3204 if (htp_state == NULL) {
3205 printf(
"no http state: ");
3209 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3211 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3212 if (tx->request_method_number != HTP_M_UNKNOWN ||
3213 h != NULL || tx->request_protocol_number != HTP_PROTOCOL_1_0)
3215 printf(
"expected method M_UNKNOWN and got %s: , expected protocol "
3216 "HTTP/1.0 and got %s \n", bstr_util_strdup_to_c(tx->request_method),
3217 bstr_util_strdup_to_c(tx->request_protocol));
3231 static int HTPParserTest04(
void)
3236 uint8_t httpbuf1[] =
"World!\r\n";
3237 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3242 memset(&ssn, 0,
sizeof(ssn));
3244 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3248 f->
proto = IPPROTO_TCP;
3254 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3260 if (htp_state == NULL) {
3261 printf(
"no http state: ");
3265 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3266 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3267 if (tx->request_method_number != HTP_M_UNKNOWN ||
3268 h != NULL || tx->request_protocol_number != HTP_PROTOCOL_0_9)
3270 printf(
"expected method M_UNKNOWN and got %s: , expected protocol "
3271 "NULL and got %s \n", bstr_util_strdup_to_c(tx->request_method),
3272 bstr_util_strdup_to_c(tx->request_protocol));
3286 static int HTPParserTest05(
void)
3288 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3289 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3290 uint8_t httpbuf2[] =
"Post D";
3291 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3292 uint8_t httpbuf3[] =
"ata is c0oL!";
3293 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3295 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3296 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3297 uint8_t httpbuf5[] =
"post R";
3298 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3299 uint8_t httpbuf6[] =
"esults are tha bomb!";
3300 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3303 memset(&ssn, 0,
sizeof(ssn));
3311 f->
proto = IPPROTO_TCP;
3341 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3343 FAIL_IF_NOT(tx->request_method_number == HTP_M_POST);
3344 FAIL_IF_NOT(tx->request_protocol_number == HTP_PROTOCOL_1_0);
3346 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3359 static int HTPParserTest06(
void)
3361 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3362 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3363 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3364 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3365 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3367 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3368 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3369 "FrontPage/5.0.2.2510\r\n"
3370 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3372 "Content-Type: text/html\r\n\r\n"
3374 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3375 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3376 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3377 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3378 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3379 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3380 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3381 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3382 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3383 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3384 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3385 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3386 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3387 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3388 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3389 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3390 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3391 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3392 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3393 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3394 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3395 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3396 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3397 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3398 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3399 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3400 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3401 "aHA=\r\n0\r\n\r\n";
3402 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3408 memset(&ssn, 0,
sizeof(ssn));
3413 f->
proto = IPPROTO_TCP;
3428 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3431 FAIL_IF(tx->request_method_number != HTP_M_GET);
3432 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
3434 FAIL_IF(tx->response_status_number != 200);
3435 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
3437 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3448 static int HTPParserTest07(
void)
3452 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3453 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3459 memset(&ssn, 0,
sizeof(ssn));
3461 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3465 f->
proto = IPPROTO_TCP;
3471 for (u = 0; u < httplen1; u++) {
3475 flags = STREAM_TOSERVER|STREAM_START;
3476 else if (u == (httplen1 - 1))
3477 flags = STREAM_TOSERVER|STREAM_EOF;
3479 flags = STREAM_TOSERVER;
3483 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3490 if (htp_state == NULL) {
3491 printf(
"no http state: ");
3495 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3496 size_t reflen =
sizeof(ref) - 1;
3498 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3504 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
3513 printf(
"normalized uri \"");
3535 static int HTPParserTest08(
void)
3539 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3540 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3562 memset(&ssn, 0,
sizeof(ssn));
3564 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3568 f->
proto = IPPROTO_TCP;
3574 flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
3578 printf(
"toserver chunk returned %" PRId32
", expected"
3585 if (htp_state == NULL) {
3586 printf(
"no http state: ");
3591 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3615 static int HTPParserTest09(
void)
3619 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3620 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3630 personality: Apache_2_2\n\
3643 memset(&ssn, 0,
sizeof(ssn));
3645 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3649 f->
proto = IPPROTO_TCP;
3655 flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
3659 printf(
"toserver chunk returned %" PRId32
", expected"
3665 if (htp_state == NULL) {
3666 printf(
"no http state: ");
3670 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3694 static int HTPParserTest10(
void)
3698 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3699 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3705 memset(&ssn, 0,
sizeof(ssn));
3707 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3711 f->
proto = IPPROTO_TCP;
3717 for (u = 0; u < httplen1; u++) {
3721 flags = STREAM_TOSERVER|STREAM_START;
3722 else if (u == (httplen1 - 1))
3723 flags = STREAM_TOSERVER|STREAM_EOF;
3725 flags = STREAM_TOSERVER;
3729 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3736 if (htp_state == NULL) {
3737 printf(
"no http state: ");
3741 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3742 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3747 char *name = bstr_util_strdup_to_c(h->name);
3752 if (strcmp(name,
"Host") != 0) {
3753 printf(
"header name not \"Host\", instead \"%s\": ", name);
3759 char *value = bstr_util_strdup_to_c(h->value);
3760 if (value == NULL) {
3764 if (strcmp(value,
"www.google.com") != 0) {
3765 printf(
"header value not \"www.google.com\", instead \"%s\": ", value);
3782 static int HTPParserTest11(
void)
3786 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3787 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3793 memset(&ssn, 0,
sizeof(ssn));
3795 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3799 f->
proto = IPPROTO_TCP;
3805 for (u = 0; u < httplen1; u++) {
3809 flags = STREAM_TOSERVER|STREAM_START;
3810 else if (u == (httplen1 - 1))
3811 flags = STREAM_TOSERVER|STREAM_EOF;
3813 flags = STREAM_TOSERVER;
3817 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3824 if (htp_state == NULL) {
3825 printf(
"no http state: ");
3829 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3835 printf(
"normalized uri len should be 2, is %"PRIuMAX,
3845 printf(
"normalized uri \"");
3863 static int HTPParserTest12(
void)
3867 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3868 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3874 memset(&ssn, 0,
sizeof(ssn));
3876 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3880 f->
proto = IPPROTO_TCP;
3886 for (u = 0; u < httplen1; u++) {
3890 flags = STREAM_TOSERVER|STREAM_START;
3891 else if (u == (httplen1 - 1))
3892 flags = STREAM_TOSERVER|STREAM_EOF;
3894 flags = STREAM_TOSERVER;
3898 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3905 if (htp_state == NULL) {
3906 printf(
"no http state: ");
3910 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3916 printf(
"normalized uri len should be 5, is %"PRIuMAX,
3929 printf(
"normalized uri \"");
3947 static int HTPParserTest13(
void)
3951 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3952 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3958 memset(&ssn, 0,
sizeof(ssn));
3960 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3964 f->
proto = IPPROTO_TCP;
3970 for (u = 0; u < httplen1; u++) {
3974 flags = STREAM_TOSERVER|STREAM_START;
3975 else if (u == (httplen1 - 1))
3976 flags = STREAM_TOSERVER|STREAM_EOF;
3978 flags = STREAM_TOSERVER;
3982 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3989 if (htp_state == NULL) {
3990 printf(
"no http state: ");
3994 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3995 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
4000 char *name = bstr_util_strdup_to_c(h->name);
4005 if (strcmp(name,
"Host") != 0) {
4006 printf(
"header name not \"Host\", instead \"%s\": ", name);
4012 char *value = bstr_util_strdup_to_c(h->value);
4013 if (value == NULL) {
4017 if (strcmp(value,
"www.google.com\rName: Value") != 0) {
4018 printf(
"header value not \"www.google.com\", instead \"");
4036 static int HTPParserConfigTest01(
void)
4050 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4051 personality: Tomcat_6_0\n\
4056 - 192.168.10.0/24\n\
4057 personality: IIS_7_0\n\
4066 outputs =
ConfGetNode(
"libhtp.default-config.personality");
4067 if (outputs == NULL) {
4072 if (outputs == NULL) {
4080 if (strcmp(node->
name,
"0") != 0) {
4087 if (strcmp(node->
name,
"apache-tomcat") != 0) {
4095 if (node2 == NULL) {
4098 if (strcmp(node2->
val,
"Tomcat_6_0") != 0) {
4113 if (strcmp(n->
name,
"0") != 0) {
4116 if (strcmp(n->
val,
"192.168.1.0/24") != 0) {
4121 if (strcmp(n->
name,
"1") != 0) {
4124 if (strcmp(n->
val,
"127.0.0.0/8") != 0) {
4129 if (strcmp(n->
name,
"2") != 0) {
4132 if (strcmp(n->
val,
"::1") != 0) {
4143 if (outputs == NULL) {
4152 if (strcmp(node->
name,
"1") != 0) {
4159 if (strcmp(node->
name,
"iis7") != 0) {
4164 if (node2 == NULL) {
4167 if (strcmp(node2->
val,
"IIS_7_0") != 0) {
4184 if (strcmp(n->
name,
"0") != 0) {
4187 if (strcmp(n->
val,
"192.168.0.0/24") != 0) {
4192 if (strcmp(n->
name,
"1") != 0) {
4195 if (strcmp(n->
val,
"192.168.10.0/24") != 0) {
4215 static int HTPParserConfigTest02(
void)
4229 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4230 personality: Tomcat_6_0\n\
4235 - 192.168.10.0/24\n\
4236 personality: IIS_7_0\n\
4247 if (cfglist.
cfg == NULL) {
4248 printf(
"No default config created.\n");
4252 if (cfgtree == NULL) {
4253 printf(
"No config tree created.\n");
4257 htp_cfg_t *htp = cfglist.
cfg;
4260 void *user_data = NULL;
4262 addr =
"192.168.10.42";
4263 if (inet_pton(AF_INET, addr, buf) == 1) {
4265 if (user_data != NULL) {
4267 htp = htp_cfg_rec->
cfg;
4271 printf(
"Could not get config for: %s\n", addr);
4276 printf(
"Failed to parse address: %s\n", addr);
4282 if (inet_pton(AF_INET6, addr, buf) == 1) {
4284 if (user_data != NULL) {
4286 htp = htp_cfg_rec->
cfg;
4290 printf(
"Could not get config for: %s\n", addr);
4295 printf(
"Failed to parse address: %s\n", addr);
4311 static int HTPParserConfigTest03(
void)
4315 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
4317 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4334 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4335 personality: Tomcat_6_0\n\
4340 - 192.168.10.0/24\n\
4341 personality: IIS_7_0\n\
4352 const char *addr =
"192.168.10.42";
4354 memset(&ssn, 0,
sizeof(ssn));
4360 f->
proto = IPPROTO_TCP;
4363 htp_cfg_t *htp = cfglist.
cfg;
4365 void *user_data = NULL;
4367 if (user_data != NULL) {
4369 htp = htp_cfg_rec->
cfg;
4373 printf(
"Could not get config for: %s\n", addr);
4380 for (u = 0; u < httplen1; u++) {
4383 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4384 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4385 else flags = STREAM_TOSERVER;
4389 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4397 if (htp_state == NULL) {
4398 printf(
"no http state: ");
4403 if (HTPStateGetTxCnt(htp_state) != 2) {
4404 printf(
"HTPStateGetTxCnt(htp_state) failure\n");
4408 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4411 if (tx->cfg != htp) {
4412 printf(
"wrong HTP config (%p instead of %p - default=%p): ",
4413 tx->cfg, htp, cfglist.
cfg);
4416 tx = HTPStateGetTx(htp_state, 1);
4419 if (tx->cfg != htp) {
4420 printf(
"wrong HTP config (%p instead of %p - default=%p): ",
4421 tx->cfg, htp, cfglist.
cfg);
4444 static int HTPParserDecodingTest01(
void)
4446 uint8_t httpbuf1[] =
4447 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4448 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4449 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4450 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4461 personality: Apache_2\n\
4469 const char *addr =
"4.3.2.1";
4470 memset(&ssn, 0,
sizeof(ssn));
4475 f->
proto = IPPROTO_TCP;
4480 for (uint32_t u = 0; u < httplen1; u++) {
4482 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4483 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4484 else flags = STREAM_TOSERVER;
4493 uint8_t ref1[] =
"/abc%2fdef";
4494 size_t reflen =
sizeof(ref1) - 1;
4496 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4506 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4507 reflen =
sizeof(ref2) - 1;
4509 tx = HTPStateGetTx(htp_state, 1);
4519 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4520 reflen =
sizeof(ref3) - 1;
4521 tx = HTPStateGetTx(htp_state, 2);
4542 static int HTPParserDecodingTest01a(
void)
4544 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4545 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4546 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4547 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4558 personality: Apache_2\n\
4566 const char *addr =
"4.3.2.1";
4567 memset(&ssn, 0,
sizeof(ssn));
4572 f->
proto = IPPROTO_TCP;
4578 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4584 uint8_t ref1[] =
"/abc%2fdef";
4585 size_t reflen =
sizeof(ref1) - 1;
4587 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4597 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4598 reflen =
sizeof(ref2) - 1;
4600 tx = HTPStateGetTx(htp_state, 1);
4610 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4611 reflen =
sizeof(ref3) - 1;
4612 tx = HTPStateGetTx(htp_state, 2);
4639 static int HTPParserDecodingTest02(
void)
4643 uint8_t httpbuf1[] =
4644 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4645 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4646 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4647 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4660 double-decode-path: no\n\
4661 double-decode-query: no\n\
4669 const char *addr =
"4.3.2.1";
4670 memset(&ssn, 0,
sizeof(ssn));
4676 f->
proto = IPPROTO_TCP;
4682 for (u = 0; u < httplen1; u++) {
4685 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4686 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4687 else flags = STREAM_TOSERVER;
4691 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4698 if (htp_state == NULL) {
4699 printf(
"no http state: ");
4703 uint8_t ref1[] =
"/abc/def";
4704 size_t reflen =
sizeof(ref1) - 1;
4706 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4712 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
4721 printf(
"normalized uri \"");
4730 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4731 reflen =
sizeof(ref2) - 1;
4733 tx = HTPStateGetTx(htp_state, 1);
4739 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
4748 printf(
"normalized uri \"");
4757 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4758 reflen =
sizeof(ref3) - 1;
4759 tx = HTPStateGetTx(htp_state, 2);
4765 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX
" (3): ",
4774 printf(
"normalized uri \"");
4803 static int HTPParserDecodingTest03(
void)
4807 uint8_t httpbuf1[] =
4808 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4809 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4810 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4823 double-decode-path: yes\n\
4824 double-decode-query: yes\n\
4832 const char *addr =
"4.3.2.1";
4833 memset(&ssn, 0,
sizeof(ssn));
4839 f->
proto = IPPROTO_TCP;
4845 for (u = 0; u < httplen1; u++) {
4848 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4849 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4850 else flags = STREAM_TOSERVER;
4854 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4861 if (htp_state == NULL) {
4862 printf(
"no http state: ");
4866 uint8_t ref1[] =
"/abc/def";
4867 size_t reflen =
sizeof(ref1) - 1;
4869 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4875 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
4884 printf(
"normalized uri \"");
4893 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4894 reflen =
sizeof(ref2) - 1;
4896 tx = HTPStateGetTx(htp_state, 1);
4902 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
4911 printf(
"normalized uri \"");
4937 static int HTPParserDecodingTest04(
void)
4941 uint8_t httpbuf1[] =
4942 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4943 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4956 double-decode-path: yes\n\
4957 double-decode-query: yes\n\
4965 const char *addr =
"4.3.2.1";
4966 memset(&ssn, 0,
sizeof(ssn));
4972 f->
proto = IPPROTO_TCP;
4978 for (u = 0; u < httplen1; u++) {
4981 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4982 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4983 else flags = STREAM_TOSERVER;
4987 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4994 if (htp_state == NULL) {
4995 printf(
"no http state: ");
4999 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
5000 size_t reflen =
sizeof(ref1) - 1;
5002 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5008 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5017 printf(
"normalized uri \"");
5043 static int HTPParserDecodingTest05(
void)
5047 uint8_t httpbuf1[] =
5048 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5049 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5062 double-decode-path: yes\n\
5063 double-decode-query: yes\n\
5071 const char *addr =
"4.3.2.1";
5072 memset(&ssn, 0,
sizeof(ssn));
5078 f->
proto = IPPROTO_TCP;
5084 for (u = 0; u < httplen1; u++) {
5087 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5088 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5089 else flags = STREAM_TOSERVER;
5093 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5100 if (htp_state == NULL) {
5101 printf(
"no http state: ");
5105 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
5106 size_t reflen =
sizeof(ref1) - 1;
5108 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5114 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5123 printf(
"normalized uri \"");
5149 static int HTPParserDecodingTest06(
void)
5153 uint8_t httpbuf1[] =
5154 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5155 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5168 double-decode-path: yes\n\
5169 double-decode-query: yes\n\
5177 const char *addr =
"4.3.2.1";
5178 memset(&ssn, 0,
sizeof(ssn));
5184 f->
proto = IPPROTO_TCP;
5190 for (u = 0; u < httplen1; u++) {
5193 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5194 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5195 else flags = STREAM_TOSERVER;
5199 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5206 if (htp_state == NULL) {
5207 printf(
"no http state: ");
5211 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
5212 size_t reflen =
sizeof(ref1) - 1;
5214 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5220 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5229 printf(
"normalized uri \"");
5255 static int HTPParserDecodingTest07(
void)
5259 uint8_t httpbuf1[] =
5260 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5261 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5274 double-decode-path: yes\n\
5275 double-decode-query: yes\n\
5276 query-plusspace-decode: yes\n\
5284 const char *addr =
"4.3.2.1";
5285 memset(&ssn, 0,
sizeof(ssn));
5291 f->
proto = IPPROTO_TCP;
5297 for (u = 0; u < httplen1; u++) {
5300 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5301 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5302 else flags = STREAM_TOSERVER;
5306 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5313 if (htp_state == NULL) {
5314 printf(
"no http state: ");
5318 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
5319 size_t reflen =
sizeof(ref1) - 1;
5321 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5327 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5336 printf(
"normalized uri \"");
5362 static int HTPParserDecodingTest08(
void)
5366 uint8_t httpbuf1[] =
5367 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
5368 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5388 const char *addr =
"4.3.2.1";
5389 memset(&ssn, 0,
sizeof(ssn));
5395 f->
proto = IPPROTO_TCP;
5401 for (u = 0; u < httplen1; u++) {
5404 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5405 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5406 else flags = STREAM_TOSERVER;
5410 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5417 if (htp_state == NULL) {
5418 printf(
"no http state: ");
5422 uint8_t ref1[] =
"/blah/";
5423 size_t reflen =
sizeof(ref1) - 1;
5425 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5431 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5440 printf(
"normalized uri \"");
5466 static int HTPParserDecodingTest09(
void)
5470 uint8_t httpbuf1[] =
5471 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
5472 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5485 uri-include-all: true\n\
5493 const char *addr =
"4.3.2.1";
5494 memset(&ssn, 0,
sizeof(ssn));
5500 f->
proto = IPPROTO_TCP;
5506 for (u = 0; u < httplen1; u++) {
5509 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5510 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5511 else flags = STREAM_TOSERVER;
5515 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5522 if (htp_state == NULL) {
5523 printf(
"no http state: ");
5527 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
5528 size_t reflen =
sizeof(ref1) - 1;
5530 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5536 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5545 printf(
"normalized uri \"");
5570 static int HTPBodyReassemblyTest01(
void)
5574 memset(&htud, 0x00,
sizeof(htud));
5576 memset(&hstate, 0x00,
sizeof(hstate));
5578 memset(&flow, 0x00,
sizeof(flow));
5581 memset(&tx, 0,
sizeof(tx));
5586 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
5587 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";
5594 const uint8_t *chunks_buffer = NULL;
5595 uint32_t chunks_buffer_len = 0;
5597 HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len);
5598 if (chunks_buffer == NULL) {
5602 printf(
"REASSCHUNK START: \n");
5604 printf(
"REASSCHUNK END: \n");
5607 htud.
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
5608 strlen(
"multipart/form-data; boundary=toto"));
5611 HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len,
false);
5626 static int HTPSegvTest01(
void)
5630 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";
5631 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5639 double-decode-path: no\n\
5640 double-decode-query: no\n\
5641 request-body-limit: 0\n\
5642 response-body-limit: 0\n\
5655 memset(&ssn, 0,
sizeof(ssn));
5657 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5661 f->
proto = IPPROTO_TCP;
5666 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
5670 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
5673 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
5676 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
5681 if (http_state == NULL) {
5682 printf(
"no http state: ");
5687 if (decoder_events != NULL) {
5688 printf(
"app events: ");
5705 static int HTPParserTest14(
void)
5716 double-decode-path: no\n\
5717 double-decode-query: no\n\
5718 request-body-limit: 0\n\
5719 response-body-limit: 0\n\
5724 memset(&ssn, 0,
sizeof(ssn));
5734 memset(httpbuf, 0x00,
len);
5737 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5738 "Host: myhost.lan\r\n"
5739 "Connection: keep-alive\r\n"
5741 "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"
5742 "Referer: http://blah.lan/\r\n"
5743 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5745 size_t o = strlen(httpbuf);
5746 for ( ; o <
len - 4; o++) {
5749 httpbuf[
len - 4] =
'\r';
5750 httpbuf[
len - 3] =
'\n';
5751 httpbuf[
len - 2] =
'\r';
5752 httpbuf[
len - 1] =
'\n';
5758 f->
proto = IPPROTO_TCP;
5763 for (u = 0; u <
len; u++) {
5766 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5767 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5768 else flags = STREAM_TOSERVER;
5776 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5778 FAIL_IF(tx->request_method_number != HTP_M_GET);
5779 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
5801 static int HTPParserTest15(
void)
5805 char *httpbuf = NULL;
5817 double-decode-path: no\n\
5818 double-decode-query: no\n\
5819 request-body-limit: 0\n\
5820 response-body-limit: 0\n\
5821 meta-field-limit: 20000\n\
5825 memset(&ssn, 0,
sizeof(ssn));
5836 memset(httpbuf, 0x00,
len);
5839 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5840 "Host: myhost.lan\r\n"
5841 "Connection: keep-alive\r\n"
5843 "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"
5844 "Referer: http://blah.lan/\r\n"
5845 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5847 size_t o = strlen(httpbuf);
5848 for ( ; o <
len - 4; o++) {
5851 httpbuf[
len - 4] =
'\r';
5852 httpbuf[
len - 3] =
'\n';
5853 httpbuf[
len - 2] =
'\r';
5854 httpbuf[
len - 1] =
'\n';
5856 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5860 f->
proto = IPPROTO_TCP;
5866 for (u = 0; u <
len; u++) {
5869 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5870 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5871 else flags = STREAM_TOSERVER;
5875 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5881 if (htp_state == NULL) {
5882 printf(
"no http state: ");
5886 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5887 if (tx == NULL || tx->request_method_number != HTP_M_GET || tx->request_protocol_number != HTP_PROTOCOL_1_1)
5889 printf(
"expected method M_GET and got %s: , expected protocol "
5890 "HTTP/1.1 and got %s \n", bstr_util_strdup_to_c(tx->request_method),
5891 bstr_util_strdup_to_c(tx->request_protocol));
5898 if (decoder_events != NULL) {
5899 printf(
"app events: ");
5909 if (httpbuf != NULL)
5919 static int HTPParserTest16(
void)
5928 memset(&ssn, 0,
sizeof(ssn));
5930 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5931 "Host: myhost.lan\r\n"
5932 "Connection: keep-alive\r\n"
5934 "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"
5935 "Referer: http://blah.lan/\r\n"
5936 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5937 "Cookie: blah\r\n\r\n";
5938 size_t len =
sizeof(httpbuf) - 1;
5940 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5944 f->
proto = IPPROTO_TCP;
5949 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5953 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
5958 if (htp_state == NULL) {
5959 printf(
"no http state: ");
5963 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5964 if (tx == NULL || tx->request_method_number != HTP_M_GET || tx->request_protocol_number != HTP_PROTOCOL_1_1)
5966 printf(
"expected method M_GET and got %s: , expected protocol "
5967 "HTTP/1.1 and got %s \n", tx ? bstr_util_strdup_to_c(tx->request_method) :
"tx null",
5968 tx ? bstr_util_strdup_to_c(tx->request_protocol) :
"tx null");
5972 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5977 if (decoder_events == NULL) {
5978 printf(
"no app events: ");
5983 printf(
"HTTP_DECODER_EVENT_METHOD_DELIM_NON_COMPLIANT not set: ");
5988 printf(
"HTTP_DECODER_EVENT_URI_DELIM_NON_COMPLIANT not set: ");
6004 static int HTPParserTest20(
void)
6007 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
6008 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
6009 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
6010 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6011 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
6012 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6013 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
6014 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
6020 memset(&ssn, 0,
sizeof(ssn));
6022 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
6025 f->
proto = IPPROTO_TCP;
6044 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
6046 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
6049 FAIL_IF(tx->request_method_number != HTP_M_GET);
6050 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
6052 FAIL_IF(tx->response_status_number != 0);
6053 FAIL_IF(tx->response_protocol_number != -1);
6063 static int HTPParserTest21(
void)
6066 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
6067 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
6068 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
6069 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6070 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
6071 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6072 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
6073 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
6079 memset(&ssn, 0,
sizeof(ssn));
6081 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
6084 f->
proto = IPPROTO_TCP;
6103 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
6105 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
6108 FAIL_IF(tx->request_method_number != HTP_M_GET);
6109 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
6111 FAIL_IF(tx->response_status_number != 0);
6112 FAIL_IF(tx->response_protocol_number != -1);
6122 static int HTPParserTest22(
void)
6125 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
6126 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
6127 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
6128 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6129 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
6130 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
6131 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6137 memset(&ssn, 0,
sizeof(ssn));
6139 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
6142 f->
proto = IPPROTO_TCP;
6157 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
6159 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
6162 FAIL_IF(tx->request_method_number != HTP_M_GET);
6163 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
6165 FAIL_IF(tx->response_status_number != -0);
6166 FAIL_IF(tx->response_protocol_number != -1);
6176 static int HTPParserTest23(
void)
6179 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
6180 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
6181 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
6182 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6183 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
6184 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
6185 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6191 memset(&ssn, 0,
sizeof(ssn));
6193 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
6196 f->
proto = IPPROTO_TCP;
6211 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
6213 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
6216 FAIL_IF(tx->request_method_number != HTP_M_GET);
6217 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
6219 FAIL_IF(tx->response_status_number != -1);
6220 FAIL_IF(tx->response_protocol_number != -2);
6230 static int HTPParserTest24(
void)
6233 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
6234 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
6235 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
6236 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6237 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
6238 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
6239 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6245 memset(&ssn, 0,
sizeof(ssn));
6247 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
6250 f->
proto = IPPROTO_TCP;
6265 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
6267 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
6270 FAIL_IF(tx->request_method_number != HTP_M_GET);
6271 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
6273 FAIL_IF(tx->response_status_number != -1);
6274 FAIL_IF(tx->response_protocol_number != HTP_PROTOCOL_1_0);
6283 static int HTPParserTest25(
void)
6290 memset(&ssn, 0,
sizeof(ssn));
6295 f->
proto = IPPROTO_TCP;
6298 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
6300 (uint8_t *)
str, strlen(
str));
6324 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
6326 (uint8_t *)
str, strlen(
str));
6360 (uint8_t *)
str, strlen(
str));
6371 (uint8_t *)
str, strlen(
str));
6391 static int HTPParserTest26(
void)
6400 request-body-limit: 1\n\
6401 response-body-limit: 1\n\
6415 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
6416 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6417 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
6418 "Content-Type: text/plain\r\n"
6419 "Content-Length: 228\r\n\r\n"
6420 "Alice was beginning to get very tired of sitting by her sister on the bank."
6421 "Alice was beginning to get very tired of sitting by her sister on the bank.";
6422 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6423 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
6424 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
6430 memset(&th_v, 0,
sizeof(th_v));
6431 memset(&f, 0,
sizeof(f));
6432 memset(&ssn, 0,
sizeof(ssn));
6439 f.
proto = IPPROTO_TCP;
6460 "(filestore; sid:1; rev:1;)");
6505 AppLayerGetFileState files = HTPGetTxFiles(tx_ptr, STREAM_TOCLIENT);
6527 static int HTPParserTest27(
void)
6530 memset(&cfg, 0,
sizeof(cfg));
6534 uint32_t
len = 1000;
6559 static void HTPParserRegisterTests(
void)
6581 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
6582 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
6583 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
6584 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
6585 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
6586 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
6587 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
6588 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
6589 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
6590 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
6592 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);