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",
206 static int HTTPGetFrameIdByName(
const char *frame_name)
215 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
221 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
222 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
223 static uint64_t HTPStateGetTxCnt(
void *alstate);
225 static void HTPParserRegisterTests(
void);
228 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
230 uint64_t
id = HTPStateGetTxCnt(s);
235 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
248 static const char *HTPLookupPersonalityString(
int p)
250 #define CASE_HTP_PERSONALITY_STRING(p) \
251 case HTP_SERVER_ ## p: return #p
254 CASE_HTP_PERSONALITY_STRING(MINIMAL);
255 CASE_HTP_PERSONALITY_STRING(GENERIC);
256 CASE_HTP_PERSONALITY_STRING(IDS);
257 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
258 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
259 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
260 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
261 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
262 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
263 CASE_HTP_PERSONALITY_STRING(APACHE_2);
277 static int HTPLookupPersonality(
const char *
str)
279 #define IF_HTP_PERSONALITY_NUM(p) \
280 if (strcasecmp(#p, str) == 0) return HTP_SERVER_ ## p
292 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
294 "longer supported by libhtp.",
297 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
298 (strcasecmp(
"APACHE_2_2",
str) == 0))
301 "longer supported by libhtp, failing back to "
302 "Apache2 personality.",
304 return HTP_SERVER_APACHE_2;
311 const uint8_t dir,
const uint8_t e)
321 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
322 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
324 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
325 if (tx == NULL && tx_id > 0)
326 tx = HTPStateGetTx(s, tx_id - 1);
341 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
355 htp_state_memuse +=
sizeof(
HtpState);
356 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
376 if (htud->
tx_data.de_state != NULL) {
402 if (s->
connp != NULL) {
406 uint64_t total_txs = HTPStateGetTxCnt(state);
408 if (s->
conn != NULL) {
409 for (tx_id = s->
tx_freed; tx_id < total_txs; tx_id++) {
410 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
413 HtpTxUserDataFree(s, htud);
414 htp_tx_set_user_data(tx, NULL);
418 htp_connp_destroy_all(s->
connp);
426 htp_state_memuse -=
sizeof(
HtpState);
427 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
440 static void HTPStateTransactionFree(
void *state, uint64_t
id)
448 htp_tx_t *tx = HTPStateGetTx(s,
id);
452 HtpTxUserDataFree(s, htud);
453 htp_tx_set_user_data(tx, NULL);
460 tx->request_progress == HTP_REQUEST_COMPLETE &&
461 tx->response_progress == HTP_RESPONSE_COMPLETE)))
463 tx->request_progress = HTP_REQUEST_COMPLETE;
464 tx->response_progress = HTP_RESPONSE_COMPLETE;
514 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
519 if (
flags & STREAM_TOCLIENT) {
529 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
546 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
547 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
549 uint32_t chunk_len = 0;
551 (content_len_so_far < (uint64_t)body_limit) &&
552 (content_len_so_far + (uint64_t)data_len) > body_limit)
554 chunk_len = (uint32_t)(body_limit - content_len_so_far);
556 (content_len_so_far < (uint64_t)stream_depth) &&
557 (content_len_so_far + (uint64_t)data_len) > stream_depth)
559 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
562 return (chunk_len == 0 ? data_len : chunk_len);
609 {
"Request line: URI contains non-compliant delimiter",
611 {
"Request line: non-compliant delimiter between Method and URI",
620 {
"Transfer-encoding has abnormal chunked value",
622 {
"Chunked transfer-encoding on HTTP/0.9 or HTTP/1.0",
625 {
"Invalid response line: invalid response status",
631 {
"Ambiguous response C-L value",
639 #define HTP_ERROR_MAX (sizeof(htp_errors) / sizeof(htp_errors[0]))
640 #define HTP_WARNING_MAX (sizeof(htp_warnings) / sizeof(htp_warnings[0]))
651 static uint8_t HTPHandleWarningGetId(
const char *
msg)
675 static uint8_t HTPHandleErrorGetId(
const char *
msg)
699 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
701 if (s == NULL || s->
conn == NULL ||
702 s->
conn->messages == NULL) {
706 size_t size = htp_list_size(s->
conn->messages);
721 htp_log_t *log = htp_list_get(s->
conn->messages,
msg);
726 htp_tx_t *tx = log->tx;
732 uint8_t
id = HTPHandleErrorGetId(log->msg);
734 id = HTPHandleWarningGetId(log->msg);
740 HTPSetEvent(s, htud, dir,
id);
747 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s, htp_tx_t *tx)
750 BUG_ON(s == NULL || tx == NULL);
752 if (tx->flags & ( HTP_REQUEST_INVALID_T_E|HTP_REQUEST_INVALID_C_L|
753 HTP_HOST_MISSING|HTP_HOST_AMBIGUOUS|HTP_HOSTU_INVALID|
760 if (tx->flags & HTP_REQUEST_INVALID_T_E)
761 HTPSetEvent(s, htud, STREAM_TOSERVER,
763 if (tx->flags & HTP_REQUEST_INVALID_C_L)
764 HTPSetEvent(s, htud, STREAM_TOSERVER,
766 if (tx->flags & HTP_HOST_MISSING)
767 HTPSetEvent(s, htud, STREAM_TOSERVER,
769 if (tx->flags & HTP_HOST_AMBIGUOUS)
770 HTPSetEvent(s, htud, STREAM_TOSERVER,
772 if (tx->flags & HTP_HOSTU_INVALID)
773 HTPSetEvent(s, htud, STREAM_TOSERVER,
775 if (tx->flags & HTP_HOSTH_INVALID)
776 HTPSetEvent(s, htud, STREAM_TOSERVER,
779 if (tx->request_auth_type == HTP_AUTH_UNRECOGNIZED) {
783 HTPSetEvent(s, htud, STREAM_TOSERVER,
786 if (tx->is_protocol_0_9 && tx->request_method_number == HTP_M_UNKNOWN &&
787 (tx->request_protocol_number == HTP_PROTOCOL_INVALID ||
788 tx->request_protocol_number == HTP_PROTOCOL_UNKNOWN)) {
792 HTPSetEvent(s, htud, STREAM_TOSERVER,
803 htp_cfg_t *htp = cfglist.
cfg;
804 void *user_data = NULL;
819 if (user_data != NULL) {
820 htp_cfg_rec = user_data;
821 htp = htp_cfg_rec->
cfg;
824 SCLogDebug(
"Using default HTP config: %p", htp);
828 #ifdef DEBUG_VALIDATION
835 hstate->
connp = htp_connp_create(htp);
836 if (hstate->
connp == NULL) {
840 hstate->
conn = htp_connp_get_connection(hstate->
connp);
842 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
843 hstate->
cfg = htp_cfg_rec;
848 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
870 StreamSlice stream_slice,
void *local_data)
880 if (NULL == hstate->
conn) {
881 if (Setup(f, hstate) != 0) {
886 hstate->
slice = &stream_slice;
888 const uint8_t *input = StreamSliceGetData(&stream_slice);
889 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
894 const int r = htp_connp_req_data(hstate->
connp, &
ts, input, input_len);
896 case HTP_STREAM_ERROR:
902 HTPHandleError(hstate, STREAM_TOSERVER);
909 htp_connp_req_close(hstate->
connp, &
ts);
911 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
915 hstate->
slice = NULL;
937 StreamSlice stream_slice,
void *local_data)
943 const uint8_t *input = StreamSliceGetData(&stream_slice);
944 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
950 if (NULL == hstate->
conn) {
951 if (Setup(f, hstate) != 0) {
956 hstate->
slice = &stream_slice;
960 uint32_t consumed = 0;
962 const int r = htp_connp_res_data(hstate->
connp, &
ts, input, input_len);
964 case HTP_STREAM_ERROR:
967 case HTP_STREAM_TUNNEL:
968 tx = htp_connp_get_out_tx(hstate->
connp);
969 if (tx != NULL && tx->response_status_number == 101) {
971 (htp_header_t *)htp_table_get_c(tx->response_headers,
"Upgrade");
976 if (tx->request_port_number != -1) {
977 dp = (uint16_t)tx->request_port_number;
979 consumed = (uint32_t)htp_connp_res_data_consumed(hstate->
connp);
980 if (bstr_cmp_c(h->value,
"h2c") == 0) {
985 hstate->
slice = NULL;
987 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
992 if (consumed > 0 && consumed < input_len) {
996 }
else if (bstr_cmp_c_nocase(h->value,
"WebSocket") == 0) {
1001 hstate->
slice = NULL;
1003 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
1008 if (consumed > 0 && consumed < input_len) {
1018 HTPHandleError(hstate, STREAM_TOCLIENT);
1025 htp_connp_close(hstate->
connp, &
ts);
1030 hstate->
slice = NULL;
1041 static int HTTPParseContentDispositionHeader(uint8_t *name,
size_t name_len,
1042 uint8_t *data,
size_t len, uint8_t **retptr,
size_t *retlen)
1045 printf(
"DATA START: \n");
1047 printf(
"DATA END: \n");
1052 for (x = 0; x <
len; x++) {
1053 if (!(isspace(data[x])))
1060 uint8_t *line = data+x;
1061 size_t line_len =
len-x;
1064 printf(
"LINE START: \n");
1066 printf(
"LINE END: \n");
1068 for (x = 0 ; x < line_len; x++) {
1070 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
1074 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
1075 uint8_t *token = line +
offset;
1076 size_t token_len = x -
offset;
1078 if ((x + 1) == line_len) {
1089 printf(
"TOKEN START: \n");
1091 printf(
"TOKEN END: \n");
1093 if (token_len > name_len) {
1094 if (name == NULL || SCMemcmpLowercase(name, token, name_len) == 0) {
1095 uint8_t *value = token + name_len;
1096 size_t value_len = token_len - name_len;
1098 if (value[0] ==
'\"') {
1102 if (value[value_len-1] ==
'\"') {
1106 printf(
"VALUE START: \n");
1108 printf(
"VALUE END: \n");
1111 *retlen = value_len;
1135 static int HtpRequestBodySetupMultipart(htp_tx_t *tx,
HtpTxUserData *htud)
1137 htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->request_headers,
1139 if (h != NULL && bstr_len(h->value) > 0) {
1140 htud->
mime_state = SCMimeStateInit(bstr_ptr(h->value), (uint32_t)bstr_len(h->value));
1157 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1160 chunks_buffer, chunks_buffer_len,
1164 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1167 if (tx && tx->
tx_data.de_state) {
1168 if (dir == STREAM_TOSERVER) {
1169 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1171 }
else if (dir == STREAM_TOCLIENT) {
1172 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1179 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1182 printf(
"CHUNK START: \n");
1184 printf(
"CHUNK END: \n");
1190 STREAM_TOSERVER) >= HTP_REQUEST_COMPLETE);
1192 const uint8_t *cur_buf = chunks_buffer;
1193 uint32_t cur_buf_len = chunks_buffer_len;
1209 const uint8_t *filename = NULL;
1210 uint16_t filename_len = 0;
1213 while (cur_buf_len > 0) {
1214 MimeParserResult r =
1215 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1219 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1223 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1234 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1235 if (filename_len > 0) {
1239 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1242 }
else if (result == -2) {
1245 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1253 }
else if (result == -2) {
1261 uint32_t lastsize = consumed;
1262 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1264 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1268 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1273 cur_buf += consumed;
1274 cur_buf_len -= consumed;
1286 htp_tx_t *tx, uint8_t *data, uint32_t data_len)
1293 uint8_t *filename = NULL;
1294 size_t filename_len = 0;
1297 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1298 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1299 filename_len = bstr_len(tx->parsed_uri->path);
1302 if (filename != NULL) {
1308 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1312 }
else if (result == -2) {
1315 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1329 }
else if (result == -2) {
1342 htp_tx_t *tx, uint8_t *data, uint32_t data_len)
1355 uint8_t *filename = NULL;
1356 size_t filename_len = 0;
1359 htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->response_headers,
1360 "Content-Disposition");
1361 if (h != NULL && bstr_len(h->value) > 0) {
1363 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1364 (uint8_t *) bstr_ptr(h->value), bstr_len(h->value), &filename, &filename_len);
1368 if (filename == NULL) {
1370 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1371 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1372 filename_len = bstr_len(tx->parsed_uri->path);
1376 if (filename != NULL) {
1378 htp_header_t *h_content_range = htp_table_get_c(tx->response_headers,
"content-range");
1384 if (h_content_range != NULL) {
1386 data_len, tx, h_content_range->value, htud);
1388 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1394 }
else if (result == -2) {
1397 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1410 }
else if (result == -2) {
1428 static int HTPCallbackRequestBodyData(htp_tx_data_t *d)
1439 printf(
"HTPBODY START: \n");
1441 printf(
"HTPBODY END: \n");
1444 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1445 if (hstate == NULL) {
1449 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1450 "%"PRIu32
"", hstate, d, d->data, (uint32_t)d->len);
1453 if (tx_ud == NULL) {
1461 if (d->tx->request_method_number == HTP_M_POST) {
1463 int r = HtpRequestBodySetupMultipart(d->tx, tx_ud);
1466 }
else if (r == 0) {
1470 }
else if (d->tx->request_method_number == HTP_M_PUT) {
1493 const uint8_t *chunks_buffer = NULL;
1494 uint32_t chunks_buffer_len = 0;
1502 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1503 if (chunks_buffer == NULL) {
1507 printf(
"REASSCHUNK START: \n");
1509 printf(
"REASSCHUNK END: \n");
1512 HtpRequestBodyHandleMultipart(hstate, tx_ud, d->tx, chunks_buffer, chunks_buffer_len,
1513 (d->data == NULL && d->len == 0));
1517 HtpRequestBodyHandlePOSTorPUT(hstate, tx_ud, d->tx, (uint8_t *)d->data,
len);
1522 SCLogDebug(
"closing file that was being stored");
1529 if (hstate->
conn != NULL) {
1530 SCLogDebug(
"checking body size %"PRIu64
" against inspect limit %u (cur %"PRIu64
", last %"PRIu64
")",
1544 const uint32_t data_size = (uint32_t)(
1565 static int HTPCallbackResponseBodyData(htp_tx_data_t *d)
1575 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1576 if (hstate == NULL) {
1580 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1581 "%"PRIu32
"", hstate, d, d->data, (uint32_t)d->len);
1584 if (tx_ud == NULL) {
1610 HtpResponseBodyHandle(hstate, tx_ud, d->tx, (uint8_t *)d->data,
len);
1613 SCLogDebug(
"closing file that was being stored");
1619 if (hstate->
conn != NULL) {
1620 SCLogDebug(
"checking body size %"PRIu64
" against inspect limit %u (cur %"PRIu64
", last %"PRIu64
")",
1633 const uint32_t data_size = (uint32_t)((uint64_t)hstate->
conn->out_data_counter -
1657 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1658 htp_state_memcnt, htp_state_memuse);
1678 htp_config_destroy(cfglist.
cfg);
1679 while (nextrec != NULL) {
1681 nextrec = nextrec->
next;
1683 htp_config_destroy(htprec->
cfg);
1689 static int HTPCallbackRequestHasTrailer(htp_tx_t *tx)
1698 static int HTPCallbackResponseHasTrailer(htp_tx_t *tx)
1711 static int HTPCallbackRequestStart(htp_tx_t *tx)
1713 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1714 if (hstate == NULL) {
1718 uint64_t consumed = hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1719 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1720 (uint64_t)hstate->
conn->in_data_counter);
1737 if (tx_ud == NULL) {
1742 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1743 htp_tx_set_user_data(tx, tx_ud);
1752 static int HTPCallbackResponseStart(htp_tx_t *tx)
1754 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1755 if (hstate == NULL) {
1759 uint64_t consumed = hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1760 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1761 (uint64_t)hstate->
conn->out_data_counter);
1776 if (tx_ud == NULL) {
1783 htp_tx_set_user_data(tx, tx_ud);
1794 static int HTPCallbackRequestComplete(htp_tx_t *tx)
1802 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1803 if (hstate == NULL) {
1807 const uint64_t abs_right_edge =
1808 hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1816 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1818 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1820 frame->
len = (int64_t)request_size;
1826 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1831 HTPErrorCheckTxRequestFlags(hstate, tx);
1836 SCLogDebug(
"closing file that was being stored");
1839 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1841 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1859 static int HTPCallbackResponseComplete(htp_tx_t *tx)
1863 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1864 if (hstate == NULL) {
1871 const uint64_t abs_right_edge =
1872 hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1879 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1881 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1883 frame->
len = (int64_t)response_size;
1891 SCLogDebug(
"closing file that was being stored");
1902 if (tx->request_method_number == HTP_M_CONNECT) {
1905 if ((tx->response_status_number >= 200) &&
1906 (tx->response_status_number < 300) &&
1909 if (tx->request_port_number != -1) {
1910 dp = (uint16_t)tx->request_port_number;
1917 tx->request_progress = HTP_REQUEST_COMPLETE;
1918 tx->response_progress = HTP_RESPONSE_COMPLETE;
1926 static int HTPCallbackRequestLine(htp_tx_t *tx)
1929 bstr *request_uri_normalized;
1930 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1934 if (request_uri_normalized == NULL)
1937 tx_ud = htp_tx_get_user_data(tx);
1939 bstr_free(request_uri_normalized);
1947 HTPErrorCheckTxRequestFlags(hstate, tx);
1952 static int HTPCallbackDoubleDecodeUriPart(htp_tx_t *tx, bstr *part)
1958 size_t prevlen = bstr_len(part);
1959 htp_status_t res = htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, part, &
flags);
1961 if (res == HTP_OK && prevlen > bstr_len(part)) {
1965 HtpState *s = htp_connp_get_user_data(tx->connp);
1968 HTPSetEvent(s, htud, STREAM_TOSERVER,
1975 static int HTPCallbackDoubleDecodeQuery(htp_tx_t *tx)
1977 if (tx->parsed_uri == NULL)
1980 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->query);
1983 static int HTPCallbackDoubleDecodePath(htp_tx_t *tx)
1985 if (tx->parsed_uri == NULL)
1988 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->path);
1991 static int HTPCallbackRequestHeaderData(htp_tx_data_t *tx_data)
1994 if (tx_data->len == 0 || tx_data->tx == NULL)
1998 if (tx_ud == NULL) {
2010 tx_data->data, tx_data->len);
2013 if (tx_data->tx && tx_data->tx->flags) {
2014 HtpState *hstate = htp_connp_get_user_data(tx_data->tx->connp);
2015 HTPErrorCheckTxRequestFlags(hstate, tx_data->tx);
2020 static int HTPCallbackResponseHeaderData(htp_tx_data_t *tx_data)
2023 if (tx_data->len == 0 || tx_data->tx == NULL)
2027 if (tx_ud == NULL) {
2039 tx_data->data, tx_data->len);
2048 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
2065 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2066 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2067 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2068 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2070 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
2071 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
2073 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
2074 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
2076 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
2077 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
2079 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
2080 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
2082 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
2083 #ifdef HAVE_HTP_CONFIG_SET_ALLOW_SPACE_URI
2084 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
2088 htp_config_set_plusspace_decode(cfg_prec->
cfg, HTP_DECODER_URLENCODED, 0);
2090 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
2091 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2095 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2096 htp_config_set_lzma_memlimit(cfg_prec->
cfg,
2099 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2100 htp_config_set_compression_bomb_limit(cfg_prec->
cfg,
2103 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2106 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2107 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
2108 htp_config_set_max_tx(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_MAX_TX_LIMIT);
2110 #ifdef HAVE_HTP_CONFIG_SET_HEADERS_LIMIT
2111 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
2112 htp_config_set_number_headers_limit(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_HEADERS_LIMIT);
2127 static int RandomGetWrap(
void)
2133 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
2135 return r % RAND_MAX;
2144 static void HTPConfigSetDefaultsPhase2(
const char *name,
HTPCfgRec *cfg_prec)
2150 long int r = RandomGetWrap();
2152 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2154 r = RandomGetWrap();
2156 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2157 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
2158 " %u and 'request-body-inspect-window' set to %u after"
2162 r = RandomGetWrap();
2164 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2166 r = RandomGetWrap();
2168 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2170 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2171 " %u and 'response-body-inspect-window' set to %u after"
2176 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2182 if (cfg_prec == NULL || s == NULL || tree == NULL)
2190 if (strcasecmp(
"address", p->
name) == 0) {
2198 if (strchr(pval->
val,
':') != NULL) {
2199 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2203 "add ipv6 server %s, ignoring",
2207 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2211 "to add ipv4 server %s, ignoring",
2217 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2219 int personality = HTPLookupPersonality(p->
val);
2223 if (personality >= 0) {
2226 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) == HTP_ERROR){
2228 "personality \"%s\", ignoring",
2232 HTPLookupPersonalityString(personality));
2238 htp_config_set_convert_lowercase(cfg_prec->
cfg, HTP_DECODER_URL_PATH, 0);
2246 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2247 strcasecmp(
"request_body_limit", p->
name) == 0) {
2249 SCLogError(
"Error parsing request-body-limit "
2250 "from conf file - %s. Killing engine",
2255 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2257 SCLogError(
"Error parsing response-body-limit "
2258 "from conf file - %s. Killing engine",
2263 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2265 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2266 "from conf file - %s. Killing engine",
2271 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2273 SCLogError(
"Error parsing request-body-inspect-window "
2274 "from conf file - %s. Killing engine",
2279 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2281 htp_config_register_request_line(cfg_prec->
cfg,
2282 HTPCallbackDoubleDecodeQuery);
2285 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2287 htp_config_register_request_line(cfg_prec->
cfg,
2288 HTPCallbackDoubleDecodePath);
2291 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2293 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2294 "from conf file - %s. Killing engine",
2299 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2301 SCLogError(
"Error parsing response-body-inspect-window "
2302 "from conf file - %s. Killing engine",
2307 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2310 SCLogError(
"Error parsing response-body-inspect-window "
2311 "from conf file - %s. Killing engine",
2315 #ifdef HAVE_HTP_CONFIG_SET_RESPONSE_DECOMPRESSION_LAYER_LIMIT
2316 htp_config_set_response_decompression_layer_limit(cfg_prec->
cfg, value);
2318 SCLogWarning(
"can't set response-body-decompress-layer-limit "
2319 "to %u, libhtp version too old",
2322 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2323 htp_config_set_backslash_convert_slashes(cfg_prec->
cfg,
2324 HTP_DECODER_URL_PATH,
2326 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2327 if (strlen(p->
val) == 1) {
2328 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg,
2329 HTP_DECODER_URL_PATH,
2333 "for libhtp param path-bestfit-replacement-char");
2335 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2336 htp_config_set_convert_lowercase(cfg_prec->
cfg,
2337 HTP_DECODER_URL_PATH,
2339 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2340 htp_config_set_nul_encoded_terminates(cfg_prec->
cfg,
2341 HTP_DECODER_URL_PATH,
2343 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2344 htp_config_set_nul_raw_terminates(cfg_prec->
cfg,
2345 HTP_DECODER_URL_PATH,
2347 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2348 htp_config_set_path_separators_compress(cfg_prec->
cfg,
2349 HTP_DECODER_URL_PATH,
2351 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2352 htp_config_set_path_separators_decode(cfg_prec->
cfg,
2353 HTP_DECODER_URL_PATH,
2355 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2356 htp_config_set_u_encoding_decode(cfg_prec->
cfg,
2357 HTP_DECODER_URL_PATH,
2359 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2360 enum htp_url_encoding_handling_t handling;
2361 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2362 handling = HTP_URL_DECODE_PRESERVE_PERCENT;
2363 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2364 handling = HTP_URL_DECODE_REMOVE_PERCENT;
2365 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2366 handling = HTP_URL_DECODE_PROCESS_INVALID;
2369 "for libhtp param path-url-encoding-invalid-handling");
2372 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg,
2373 HTP_DECODER_URL_PATH,
2375 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2376 htp_config_set_utf8_convert_bestfit(cfg_prec->
cfg,
2377 HTP_DECODER_URL_PATH,
2379 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2383 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2384 htp_config_set_plusspace_decode(cfg_prec->
cfg,
2385 HTP_DECODER_URLENCODED,
2387 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2391 "from conf file - %s. Killing engine",
2397 "from conf file cannot be 0. Killing engine");
2400 htp_config_set_field_limits(cfg_prec->
cfg,
2403 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2404 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2407 FatalError(
"failed to parse 'lzma-memlimit' "
2408 "from conf file - %s.",
2413 "from conf file cannot be 0.");
2416 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2417 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2419 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2420 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2422 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2427 "from conf file - %s.",
2430 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2431 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2434 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2435 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2438 FatalError(
"failed to parse 'compression-bomb-limit' "
2439 "from conf file - %s.",
2444 "from conf file cannot be 0.");
2447 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2448 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2450 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2451 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2455 FatalError(
"failed to parse 'decompression-time-limit' "
2456 "from conf file - %s.",
2459 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2460 htp_config_set_compression_time_limit(cfg_prec->
cfg, (
size_t)limit);
2462 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2463 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2467 "from conf file - %s.",
2471 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2472 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2474 #ifdef HAVE_HTP_CONFIG_SET_HEADERS_LIMIT
2475 }
else if (strcasecmp(
"headers-limit", p->
name) == 0) {
2478 FatalError(
"failed to parse 'headers-limit' "
2479 "from conf file - %s.",
2482 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2483 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2485 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2489 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2492 (
const char *)p->
val, 0, 100) < 0) {
2494 "-inspection-range setting from conf file - \"%s\"."
2495 " It should be a valid integer less than or equal to 100."
2501 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2507 if (strcmp(
"auto", p->
val) != 0) {
2516 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2520 if (strcasecmp(
"enabled", pval->
name) == 0) {
2528 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2529 if (strcasecmp(
"no", pval->
val) == 0) {
2531 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2533 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2535 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2539 "swf-decompression.type: %s - "
2544 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2546 SCLogError(
"Error parsing swf-decompression.compression-depth "
2547 "from conf file - %s. Killing engine",
2551 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2553 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2554 "from conf file - %s. Killing engine",
2564 "default config: %s",
2574 cfglist.
next = NULL;
2581 if (NULL == cfgtree)
2585 cfglist.
cfg = htp_config_create();
2586 if (NULL == cfglist.
cfg) {
2587 FatalError(
"Failed to create HTP default config");
2590 HTPConfigSetDefaultsPhase1(&cfglist);
2591 if (
ConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2592 HTPConfigParseParameters(&cfglist,
ConfGetNode(
"libhtp.default-config"),
2595 HTPConfigParseParameters(&cfglist,
ConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), cfgtree);
2597 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2603 if (server_config == NULL) {
2604 server_config =
ConfGetNode(
"libhtp.server-config");
2605 if (server_config == NULL) {
2606 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2610 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2629 cfglist.
next = htprec;
2632 cfglist.
next->
cfg = htp_config_create();
2633 if (NULL == cfglist.
next->
cfg) {
2634 FatalError(
"Failed to create HTP server config");
2637 HTPConfigSetDefaultsPhase1(htprec);
2638 HTPConfigParseParameters(htprec, s, cfgtree);
2639 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2649 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2660 static AppLayerGetFileState HTPGetTxFiles(
void *txv, uint8_t direction)
2662 AppLayerGetFileState files = { .fc = NULL, .cfg = &
htp_sbcfg };
2663 htp_tx_t *tx = (htp_tx_t *)txv;
2666 if (direction & STREAM_TOCLIENT) {
2675 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2677 if (direction & STREAM_TOSERVER)
2678 return ((htp_tx_t *)tx)->request_progress;
2680 return ((htp_tx_t *)tx)->response_progress;
2683 static uint64_t HTPStateGetTxCnt(
void *alstate)
2687 if (http_state != NULL && http_state->
conn != NULL) {
2688 const int64_t size = (int64_t)htp_list_size(http_state->
conn->transactions);
2692 return (uint64_t)size + http_state->
tx_freed;
2698 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2702 if (http_state != NULL && http_state->
conn != NULL && tx_id >= http_state->
tx_freed)
2703 return htp_list_get(http_state->
conn->transactions, tx_id - http_state->
tx_freed);
2712 if (http_state != NULL && http_state->
conn != NULL) {
2713 size_t txid = HTPStateGetTxCnt(http_state);
2715 return htp_list_get(http_state->
conn->transactions, txid - http_state->
tx_freed - 1);
2721 static int HTPStateGetEventInfo(
const char *event_name,
2722 int *event_id, AppLayerEventType *event_type)
2725 if (*event_id == -1) {
2727 "http's enum map table.",
2733 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2738 static int HTPStateGetEventInfoById(
int event_id,
const char **event_name,
2739 AppLayerEventType *event_type)
2742 if (*event_name == NULL) {
2744 "http's enum map table.",
2750 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2757 htp_tx_t *tx = (htp_tx_t *)vtx;
2765 static AppLayerStateData *HTPGetStateData(
void *vstate)
2771 static int HTPRegisterPatternsForProtocolDetection(
void)
2773 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2774 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2775 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2776 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2777 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2778 const char *spacings[] = {
"|20|",
"|09|", NULL };
2779 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2784 int register_result;
2785 char method_buffer[32] =
"";
2788 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2789 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2792 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2799 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2800 if (register_result < 0) {
2807 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2809 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2811 if (register_result < 0) {
2827 const char *proto_name =
"http";
2832 if (HTPRegisterPatternsForProtocolDetection() < 0)
2835 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2850 ALPROTO_HTTP1, HTP_REQUEST_COMPLETE, HTP_RESPONSE_COMPLETE);
2862 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2864 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2870 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2873 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2877 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2893 cfglist_backup = cfglist;
2898 cfglist = cfglist_backup;
2903 static int HTPParserTest01(
void)
2905 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2907 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2910 memset(&ssn, 0,
sizeof(ssn));
2918 f->
proto = IPPROTO_TCP;
2924 for (u = 0; u < httplen1; u++) {
2928 flags = STREAM_TOSERVER|STREAM_START;
2929 else if (u == (httplen1 - 1))
2930 flags = STREAM_TOSERVER|STREAM_EOF;
2932 flags = STREAM_TOSERVER;
2941 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2944 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
2947 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
2948 FAIL_IF(tx->request_method_number != HTP_M_POST);
2949 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
2958 static int HTPParserTest01b(
void)
2960 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2962 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2965 memset(&ssn, 0,
sizeof(ssn));
2973 f->
proto = IPPROTO_TCP;
2978 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2985 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2988 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
2991 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
2992 FAIL_IF(tx->request_method_number != HTP_M_POST);
2993 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
3002 static int HTPParserTest01c(
void)
3004 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
3006 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3009 memset(&ssn, 0,
sizeof(ssn));
3017 f->
proto = IPPROTO_TCP;
3023 for (u = 0; u < httplen1; u++) {
3027 flags = STREAM_TOSERVER|STREAM_START;
3028 else if (u == (httplen1 - 1))
3029 flags = STREAM_TOSERVER|STREAM_EOF;
3031 flags = STREAM_TOSERVER;
3040 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3043 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3046 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
3047 FAIL_IF(tx->request_method_number != HTP_M_POST);
3048 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
3058 static int HTPParserTest01a(
void)
3062 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3064 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);
3076 f->
proto = IPPROTO_TCP;
3082 for (u = 0; u < httplen1; u++) {
3086 flags = STREAM_TOSERVER|STREAM_START;
3087 else if (u == (httplen1 - 1))
3088 flags = STREAM_TOSERVER|STREAM_EOF;
3090 flags = STREAM_TOSERVER;
3094 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3101 if (htp_state == NULL) {
3102 printf(
"no http state: ");
3106 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3107 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3108 if (strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0")
3109 || tx->request_method_number != HTP_M_POST ||
3110 tx->request_protocol_number != HTP_PROTOCOL_1_0)
3112 printf(
"expected header value: Victor/1.0 and got %s: and expected"
3113 " method: POST and got %s, expected protocol number HTTP/1.0"
3114 " and got: %s \n", bstr_util_strdup_to_c(h->value),
3115 bstr_util_strdup_to_c(tx->request_method),
3116 bstr_util_strdup_to_c(tx->request_protocol));
3129 static int HTPParserTest02(
void)
3133 uint8_t httpbuf1[] =
"POST";
3134 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3139 memset(&ssn, 0,
sizeof(ssn));
3141 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3145 f->
proto = IPPROTO_TCP;
3151 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3153 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3158 if (http_state == NULL) {
3159 printf(
"no http state: ");
3163 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3165 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3169 char *method = bstr_util_strdup_to_c(tx->request_method);
3172 FAIL_IF(strcmp(method,
"POST") != 0);
3186 static int HTPParserTest03(
void)
3190 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
3191 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3197 memset(&ssn, 0,
sizeof(ssn));
3199 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3203 f->
proto = IPPROTO_TCP;
3209 for (u = 0; u < httplen1; u++) {
3212 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3213 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3214 else flags = STREAM_TOSERVER;
3218 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3224 if (htp_state == NULL) {
3225 printf(
"no http state: ");
3229 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3231 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3232 if (tx->request_method_number != HTP_M_UNKNOWN ||
3233 h != NULL || tx->request_protocol_number != HTP_PROTOCOL_1_0)
3235 printf(
"expected method M_UNKNOWN and got %s: , expected protocol "
3236 "HTTP/1.0 and got %s \n", bstr_util_strdup_to_c(tx->request_method),
3237 bstr_util_strdup_to_c(tx->request_protocol));
3251 static int HTPParserTest04(
void)
3256 uint8_t httpbuf1[] =
"World!\r\n";
3257 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3262 memset(&ssn, 0,
sizeof(ssn));
3264 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3268 f->
proto = IPPROTO_TCP;
3274 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3280 if (htp_state == NULL) {
3281 printf(
"no http state: ");
3285 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3286 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3287 if (tx->request_method_number != HTP_M_UNKNOWN ||
3288 h != NULL || tx->request_protocol_number != HTP_PROTOCOL_0_9)
3290 printf(
"expected method M_UNKNOWN and got %s: , expected protocol "
3291 "NULL and got %s \n", bstr_util_strdup_to_c(tx->request_method),
3292 bstr_util_strdup_to_c(tx->request_protocol));
3306 static int HTPParserTest05(
void)
3308 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3309 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3310 uint8_t httpbuf2[] =
"Post D";
3311 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3312 uint8_t httpbuf3[] =
"ata is c0oL!";
3313 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3315 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3316 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3317 uint8_t httpbuf5[] =
"post R";
3318 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3319 uint8_t httpbuf6[] =
"esults are tha bomb!";
3320 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3323 memset(&ssn, 0,
sizeof(ssn));
3331 f->
proto = IPPROTO_TCP;
3361 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3363 FAIL_IF_NOT(tx->request_method_number == HTP_M_POST);
3364 FAIL_IF_NOT(tx->request_protocol_number == HTP_PROTOCOL_1_0);
3366 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3379 static int HTPParserTest06(
void)
3381 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3382 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3383 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3384 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3385 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3387 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3388 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3389 "FrontPage/5.0.2.2510\r\n"
3390 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3392 "Content-Type: text/html\r\n\r\n"
3394 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3395 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3396 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3397 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3398 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3399 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3400 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3401 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3402 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3403 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3404 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3405 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3406 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3407 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3408 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3409 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3410 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3411 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3412 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3413 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3414 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3415 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3416 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3417 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3418 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3419 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3420 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3421 "aHA=\r\n0\r\n\r\n";
3422 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3428 memset(&ssn, 0,
sizeof(ssn));
3433 f->
proto = IPPROTO_TCP;
3448 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3451 FAIL_IF(tx->request_method_number != HTP_M_GET);
3452 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
3454 FAIL_IF(tx->response_status_number != 200);
3455 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
3457 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3468 static int HTPParserTest07(
void)
3472 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3473 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3479 memset(&ssn, 0,
sizeof(ssn));
3481 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3485 f->
proto = IPPROTO_TCP;
3491 for (u = 0; u < httplen1; u++) {
3495 flags = STREAM_TOSERVER|STREAM_START;
3496 else if (u == (httplen1 - 1))
3497 flags = STREAM_TOSERVER|STREAM_EOF;
3499 flags = STREAM_TOSERVER;
3503 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3510 if (htp_state == NULL) {
3511 printf(
"no http state: ");
3515 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3516 size_t reflen =
sizeof(ref) - 1;
3518 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3524 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
3533 printf(
"normalized uri \"");
3555 static int HTPParserTest08(
void)
3559 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3560 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3582 memset(&ssn, 0,
sizeof(ssn));
3584 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3588 f->
proto = IPPROTO_TCP;
3594 flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
3598 printf(
"toserver chunk returned %" PRId32
", expected"
3605 if (htp_state == NULL) {
3606 printf(
"no http state: ");
3611 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3635 static int HTPParserTest09(
void)
3639 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3640 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3650 personality: Apache_2_2\n\
3663 memset(&ssn, 0,
sizeof(ssn));
3665 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3669 f->
proto = IPPROTO_TCP;
3675 flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
3679 printf(
"toserver chunk returned %" PRId32
", expected"
3685 if (htp_state == NULL) {
3686 printf(
"no http state: ");
3690 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3714 static int HTPParserTest10(
void)
3718 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3719 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3725 memset(&ssn, 0,
sizeof(ssn));
3727 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3731 f->
proto = IPPROTO_TCP;
3737 for (u = 0; u < httplen1; u++) {
3741 flags = STREAM_TOSERVER|STREAM_START;
3742 else if (u == (httplen1 - 1))
3743 flags = STREAM_TOSERVER|STREAM_EOF;
3745 flags = STREAM_TOSERVER;
3749 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3756 if (htp_state == NULL) {
3757 printf(
"no http state: ");
3761 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3762 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3767 char *name = bstr_util_strdup_to_c(h->name);
3772 if (strcmp(name,
"Host") != 0) {
3773 printf(
"header name not \"Host\", instead \"%s\": ", name);
3779 char *value = bstr_util_strdup_to_c(h->value);
3780 if (value == NULL) {
3784 if (strcmp(value,
"www.google.com") != 0) {
3785 printf(
"header value not \"www.google.com\", instead \"%s\": ", value);
3802 static int HTPParserTest11(
void)
3806 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3807 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3813 memset(&ssn, 0,
sizeof(ssn));
3815 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3819 f->
proto = IPPROTO_TCP;
3825 for (u = 0; u < httplen1; u++) {
3829 flags = STREAM_TOSERVER|STREAM_START;
3830 else if (u == (httplen1 - 1))
3831 flags = STREAM_TOSERVER|STREAM_EOF;
3833 flags = STREAM_TOSERVER;
3837 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3844 if (htp_state == NULL) {
3845 printf(
"no http state: ");
3849 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3855 printf(
"normalized uri len should be 2, is %"PRIuMAX,
3865 printf(
"normalized uri \"");
3883 static int HTPParserTest12(
void)
3887 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3888 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3894 memset(&ssn, 0,
sizeof(ssn));
3896 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3900 f->
proto = IPPROTO_TCP;
3906 for (u = 0; u < httplen1; u++) {
3910 flags = STREAM_TOSERVER|STREAM_START;
3911 else if (u == (httplen1 - 1))
3912 flags = STREAM_TOSERVER|STREAM_EOF;
3914 flags = STREAM_TOSERVER;
3918 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3925 if (htp_state == NULL) {
3926 printf(
"no http state: ");
3930 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3936 printf(
"normalized uri len should be 5, is %"PRIuMAX,
3949 printf(
"normalized uri \"");
3967 static int HTPParserTest13(
void)
3971 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3972 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3978 memset(&ssn, 0,
sizeof(ssn));
3980 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3984 f->
proto = IPPROTO_TCP;
3990 for (u = 0; u < httplen1; u++) {
3994 flags = STREAM_TOSERVER|STREAM_START;
3995 else if (u == (httplen1 - 1))
3996 flags = STREAM_TOSERVER|STREAM_EOF;
3998 flags = STREAM_TOSERVER;
4002 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4009 if (htp_state == NULL) {
4010 printf(
"no http state: ");
4014 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4015 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
4020 char *name = bstr_util_strdup_to_c(h->name);
4025 if (strcmp(name,
"Host") != 0) {
4026 printf(
"header name not \"Host\", instead \"%s\": ", name);
4032 char *value = bstr_util_strdup_to_c(h->value);
4033 if (value == NULL) {
4037 if (strcmp(value,
"www.google.com\rName: Value") != 0) {
4038 printf(
"header value not \"www.google.com\", instead \"");
4056 static int HTPParserConfigTest01(
void)
4070 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4071 personality: Tomcat_6_0\n\
4076 - 192.168.10.0/24\n\
4077 personality: IIS_7_0\n\
4086 outputs =
ConfGetNode(
"libhtp.default-config.personality");
4087 if (outputs == NULL) {
4092 if (outputs == NULL) {
4100 if (strcmp(node->
name,
"0") != 0) {
4107 if (strcmp(node->
name,
"apache-tomcat") != 0) {
4115 if (node2 == NULL) {
4118 if (strcmp(node2->
val,
"Tomcat_6_0") != 0) {
4133 if (strcmp(n->
name,
"0") != 0) {
4136 if (strcmp(n->
val,
"192.168.1.0/24") != 0) {
4141 if (strcmp(n->
name,
"1") != 0) {
4144 if (strcmp(n->
val,
"127.0.0.0/8") != 0) {
4149 if (strcmp(n->
name,
"2") != 0) {
4152 if (strcmp(n->
val,
"::1") != 0) {
4163 if (outputs == NULL) {
4172 if (strcmp(node->
name,
"1") != 0) {
4179 if (strcmp(node->
name,
"iis7") != 0) {
4184 if (node2 == NULL) {
4187 if (strcmp(node2->
val,
"IIS_7_0") != 0) {
4204 if (strcmp(n->
name,
"0") != 0) {
4207 if (strcmp(n->
val,
"192.168.0.0/24") != 0) {
4212 if (strcmp(n->
name,
"1") != 0) {
4215 if (strcmp(n->
val,
"192.168.10.0/24") != 0) {
4235 static int HTPParserConfigTest02(
void)
4249 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4250 personality: Tomcat_6_0\n\
4255 - 192.168.10.0/24\n\
4256 personality: IIS_7_0\n\
4267 if (cfglist.
cfg == NULL) {
4268 printf(
"No default config created.\n");
4272 if (cfgtree == NULL) {
4273 printf(
"No config tree created.\n");
4277 htp_cfg_t *htp = cfglist.
cfg;
4280 void *user_data = NULL;
4282 addr =
"192.168.10.42";
4283 if (inet_pton(AF_INET, addr, buf) == 1) {
4285 if (user_data != NULL) {
4287 htp = htp_cfg_rec->
cfg;
4291 printf(
"Could not get config for: %s\n", addr);
4296 printf(
"Failed to parse address: %s\n", addr);
4302 if (inet_pton(AF_INET6, addr, buf) == 1) {
4304 if (user_data != NULL) {
4306 htp = htp_cfg_rec->
cfg;
4310 printf(
"Could not get config for: %s\n", addr);
4315 printf(
"Failed to parse address: %s\n", addr);
4331 static int HTPParserConfigTest03(
void)
4335 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
4337 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4354 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4355 personality: Tomcat_6_0\n\
4360 - 192.168.10.0/24\n\
4361 personality: IIS_7_0\n\
4372 const char *addr =
"192.168.10.42";
4374 memset(&ssn, 0,
sizeof(ssn));
4380 f->
proto = IPPROTO_TCP;
4383 htp_cfg_t *htp = cfglist.
cfg;
4385 void *user_data = NULL;
4387 if (user_data != NULL) {
4389 htp = htp_cfg_rec->
cfg;
4393 printf(
"Could not get config for: %s\n", addr);
4400 for (u = 0; u < httplen1; u++) {
4403 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4404 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4405 else flags = STREAM_TOSERVER;
4409 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4417 if (htp_state == NULL) {
4418 printf(
"no http state: ");
4423 if (HTPStateGetTxCnt(htp_state) != 2) {
4424 printf(
"HTPStateGetTxCnt(htp_state) failure\n");
4428 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4431 if (tx->cfg != htp) {
4432 printf(
"wrong HTP config (%p instead of %p - default=%p): ",
4433 tx->cfg, htp, cfglist.
cfg);
4436 tx = HTPStateGetTx(htp_state, 1);
4439 if (tx->cfg != htp) {
4440 printf(
"wrong HTP config (%p instead of %p - default=%p): ",
4441 tx->cfg, htp, cfglist.
cfg);
4464 static int HTPParserDecodingTest01(
void)
4466 uint8_t httpbuf1[] =
4467 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4468 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4469 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4470 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4481 personality: Apache_2\n\
4489 const char *addr =
"4.3.2.1";
4490 memset(&ssn, 0,
sizeof(ssn));
4495 f->
proto = IPPROTO_TCP;
4500 for (uint32_t u = 0; u < httplen1; u++) {
4502 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4503 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4504 else flags = STREAM_TOSERVER;
4513 uint8_t ref1[] =
"/abc%2fdef";
4514 size_t reflen =
sizeof(ref1) - 1;
4516 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4526 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4527 reflen =
sizeof(ref2) - 1;
4529 tx = HTPStateGetTx(htp_state, 1);
4539 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4540 reflen =
sizeof(ref3) - 1;
4541 tx = HTPStateGetTx(htp_state, 2);
4562 static int HTPParserDecodingTest01a(
void)
4564 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4565 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4566 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4567 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4578 personality: Apache_2\n\
4586 const char *addr =
"4.3.2.1";
4587 memset(&ssn, 0,
sizeof(ssn));
4592 f->
proto = IPPROTO_TCP;
4598 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4604 uint8_t ref1[] =
"/abc%2fdef";
4605 size_t reflen =
sizeof(ref1) - 1;
4607 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4617 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4618 reflen =
sizeof(ref2) - 1;
4620 tx = HTPStateGetTx(htp_state, 1);
4630 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4631 reflen =
sizeof(ref3) - 1;
4632 tx = HTPStateGetTx(htp_state, 2);
4659 static int HTPParserDecodingTest02(
void)
4663 uint8_t httpbuf1[] =
4664 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4665 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4666 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4667 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4680 double-decode-path: no\n\
4681 double-decode-query: no\n\
4689 const char *addr =
"4.3.2.1";
4690 memset(&ssn, 0,
sizeof(ssn));
4696 f->
proto = IPPROTO_TCP;
4702 for (u = 0; u < httplen1; u++) {
4705 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4706 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4707 else flags = STREAM_TOSERVER;
4711 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4718 if (htp_state == NULL) {
4719 printf(
"no http state: ");
4723 uint8_t ref1[] =
"/abc/def";
4724 size_t reflen =
sizeof(ref1) - 1;
4726 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4732 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
4741 printf(
"normalized uri \"");
4750 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4751 reflen =
sizeof(ref2) - 1;
4753 tx = HTPStateGetTx(htp_state, 1);
4759 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
4768 printf(
"normalized uri \"");
4777 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4778 reflen =
sizeof(ref3) - 1;
4779 tx = HTPStateGetTx(htp_state, 2);
4785 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX
" (3): ",
4794 printf(
"normalized uri \"");
4823 static int HTPParserDecodingTest03(
void)
4827 uint8_t httpbuf1[] =
4828 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4829 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4830 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4843 double-decode-path: yes\n\
4844 double-decode-query: yes\n\
4852 const char *addr =
"4.3.2.1";
4853 memset(&ssn, 0,
sizeof(ssn));
4859 f->
proto = IPPROTO_TCP;
4865 for (u = 0; u < httplen1; u++) {
4868 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4869 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4870 else flags = STREAM_TOSERVER;
4874 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4881 if (htp_state == NULL) {
4882 printf(
"no http state: ");
4886 uint8_t ref1[] =
"/abc/def";
4887 size_t reflen =
sizeof(ref1) - 1;
4889 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4895 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
4904 printf(
"normalized uri \"");
4913 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4914 reflen =
sizeof(ref2) - 1;
4916 tx = HTPStateGetTx(htp_state, 1);
4922 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
4931 printf(
"normalized uri \"");
4957 static int HTPParserDecodingTest04(
void)
4961 uint8_t httpbuf1[] =
4962 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4963 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4976 double-decode-path: yes\n\
4977 double-decode-query: yes\n\
4985 const char *addr =
"4.3.2.1";
4986 memset(&ssn, 0,
sizeof(ssn));
4992 f->
proto = IPPROTO_TCP;
4998 for (u = 0; u < httplen1; u++) {
5001 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5002 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5003 else flags = STREAM_TOSERVER;
5007 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5014 if (htp_state == NULL) {
5015 printf(
"no http state: ");
5019 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
5020 size_t reflen =
sizeof(ref1) - 1;
5022 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5028 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5037 printf(
"normalized uri \"");
5063 static int HTPParserDecodingTest05(
void)
5067 uint8_t httpbuf1[] =
5068 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5069 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5082 double-decode-path: yes\n\
5083 double-decode-query: yes\n\
5091 const char *addr =
"4.3.2.1";
5092 memset(&ssn, 0,
sizeof(ssn));
5098 f->
proto = IPPROTO_TCP;
5104 for (u = 0; u < httplen1; u++) {
5107 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5108 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5109 else flags = STREAM_TOSERVER;
5113 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5120 if (htp_state == NULL) {
5121 printf(
"no http state: ");
5125 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
5126 size_t reflen =
sizeof(ref1) - 1;
5128 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5134 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5143 printf(
"normalized uri \"");
5169 static int HTPParserDecodingTest06(
void)
5173 uint8_t httpbuf1[] =
5174 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5175 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5188 double-decode-path: yes\n\
5189 double-decode-query: yes\n\
5197 const char *addr =
"4.3.2.1";
5198 memset(&ssn, 0,
sizeof(ssn));
5204 f->
proto = IPPROTO_TCP;
5210 for (u = 0; u < httplen1; u++) {
5213 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5214 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5215 else flags = STREAM_TOSERVER;
5219 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5226 if (htp_state == NULL) {
5227 printf(
"no http state: ");
5231 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
5232 size_t reflen =
sizeof(ref1) - 1;
5234 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5240 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5249 printf(
"normalized uri \"");
5275 static int HTPParserDecodingTest07(
void)
5279 uint8_t httpbuf1[] =
5280 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5281 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5294 double-decode-path: yes\n\
5295 double-decode-query: yes\n\
5296 query-plusspace-decode: yes\n\
5304 const char *addr =
"4.3.2.1";
5305 memset(&ssn, 0,
sizeof(ssn));
5311 f->
proto = IPPROTO_TCP;
5317 for (u = 0; u < httplen1; u++) {
5320 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5321 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5322 else flags = STREAM_TOSERVER;
5326 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5333 if (htp_state == NULL) {
5334 printf(
"no http state: ");
5338 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
5339 size_t reflen =
sizeof(ref1) - 1;
5341 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5347 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5356 printf(
"normalized uri \"");
5382 static int HTPParserDecodingTest08(
void)
5386 uint8_t httpbuf1[] =
5387 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
5388 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5408 const char *addr =
"4.3.2.1";
5409 memset(&ssn, 0,
sizeof(ssn));
5415 f->
proto = IPPROTO_TCP;
5421 for (u = 0; u < httplen1; u++) {
5424 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5425 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5426 else flags = STREAM_TOSERVER;
5430 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5437 if (htp_state == NULL) {
5438 printf(
"no http state: ");
5442 uint8_t ref1[] =
"/blah/";
5443 size_t reflen =
sizeof(ref1) - 1;
5445 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5451 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5460 printf(
"normalized uri \"");
5486 static int HTPParserDecodingTest09(
void)
5490 uint8_t httpbuf1[] =
5491 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
5492 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5505 uri-include-all: true\n\
5513 const char *addr =
"4.3.2.1";
5514 memset(&ssn, 0,
sizeof(ssn));
5520 f->
proto = IPPROTO_TCP;
5526 for (u = 0; u < httplen1; u++) {
5529 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5530 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5531 else flags = STREAM_TOSERVER;
5535 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5542 if (htp_state == NULL) {
5543 printf(
"no http state: ");
5547 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
5548 size_t reflen =
sizeof(ref1) - 1;
5550 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5556 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5565 printf(
"normalized uri \"");
5590 static int HTPBodyReassemblyTest01(
void)
5594 memset(&htud, 0x00,
sizeof(htud));
5596 memset(&hstate, 0x00,
sizeof(hstate));
5598 memset(&flow, 0x00,
sizeof(flow));
5601 memset(&tx, 0,
sizeof(tx));
5606 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
5607 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";
5614 const uint8_t *chunks_buffer = NULL;
5615 uint32_t chunks_buffer_len = 0;
5617 HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len);
5618 if (chunks_buffer == NULL) {
5622 printf(
"REASSCHUNK START: \n");
5624 printf(
"REASSCHUNK END: \n");
5627 htud.
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
5628 strlen(
"multipart/form-data; boundary=toto"));
5631 HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len,
false);
5646 static int HTPSegvTest01(
void)
5650 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";
5651 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5659 double-decode-path: no\n\
5660 double-decode-query: no\n\
5661 request-body-limit: 0\n\
5662 response-body-limit: 0\n\
5675 memset(&ssn, 0,
sizeof(ssn));
5677 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5681 f->
proto = IPPROTO_TCP;
5686 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
5690 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
5693 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
5696 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
5701 if (http_state == NULL) {
5702 printf(
"no http state: ");
5707 if (decoder_events != NULL) {
5708 printf(
"app events: ");
5725 static int HTPParserTest14(
void)
5736 double-decode-path: no\n\
5737 double-decode-query: no\n\
5738 request-body-limit: 0\n\
5739 response-body-limit: 0\n\
5744 memset(&ssn, 0,
sizeof(ssn));
5754 memset(httpbuf, 0x00,
len);
5757 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5758 "Host: myhost.lan\r\n"
5759 "Connection: keep-alive\r\n"
5761 "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"
5762 "Referer: http://blah.lan/\r\n"
5763 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5765 size_t o = strlen(httpbuf);
5766 for ( ; o <
len - 4; o++) {
5769 httpbuf[
len - 4] =
'\r';
5770 httpbuf[
len - 3] =
'\n';
5771 httpbuf[
len - 2] =
'\r';
5772 httpbuf[
len - 1] =
'\n';
5778 f->
proto = IPPROTO_TCP;
5783 for (u = 0; u <
len; u++) {
5786 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5787 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5788 else flags = STREAM_TOSERVER;
5796 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5798 FAIL_IF(tx->request_method_number != HTP_M_GET);
5799 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
5821 static int HTPParserTest15(
void)
5825 char *httpbuf = NULL;
5837 double-decode-path: no\n\
5838 double-decode-query: no\n\
5839 request-body-limit: 0\n\
5840 response-body-limit: 0\n\
5841 meta-field-limit: 20000\n\
5845 memset(&ssn, 0,
sizeof(ssn));
5856 memset(httpbuf, 0x00,
len);
5859 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5860 "Host: myhost.lan\r\n"
5861 "Connection: keep-alive\r\n"
5863 "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"
5864 "Referer: http://blah.lan/\r\n"
5865 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5867 size_t o = strlen(httpbuf);
5868 for ( ; o <
len - 4; o++) {
5871 httpbuf[
len - 4] =
'\r';
5872 httpbuf[
len - 3] =
'\n';
5873 httpbuf[
len - 2] =
'\r';
5874 httpbuf[
len - 1] =
'\n';
5876 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5880 f->
proto = IPPROTO_TCP;
5886 for (u = 0; u <
len; u++) {
5889 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5890 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5891 else flags = STREAM_TOSERVER;
5895 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5901 if (htp_state == NULL) {
5902 printf(
"no http state: ");
5906 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5907 if (tx == NULL || tx->request_method_number != HTP_M_GET || tx->request_protocol_number != HTP_PROTOCOL_1_1)
5909 printf(
"expected method M_GET and got %s: , expected protocol "
5910 "HTTP/1.1 and got %s \n", bstr_util_strdup_to_c(tx->request_method),
5911 bstr_util_strdup_to_c(tx->request_protocol));
5918 if (decoder_events != NULL) {
5919 printf(
"app events: ");
5929 if (httpbuf != NULL)
5939 static int HTPParserTest16(
void)
5948 memset(&ssn, 0,
sizeof(ssn));
5950 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5951 "Host: myhost.lan\r\n"
5952 "Connection: keep-alive\r\n"
5954 "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"
5955 "Referer: http://blah.lan/\r\n"
5956 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5957 "Cookie: blah\r\n\r\n";
5958 size_t len =
sizeof(httpbuf) - 1;
5960 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5964 f->
proto = IPPROTO_TCP;
5969 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5973 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
5978 if (htp_state == NULL) {
5979 printf(
"no http state: ");
5983 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5984 if (tx == NULL || tx->request_method_number != HTP_M_GET || tx->request_protocol_number != HTP_PROTOCOL_1_1)
5986 printf(
"expected method M_GET and got %s: , expected protocol "
5987 "HTTP/1.1 and got %s \n", tx ? bstr_util_strdup_to_c(tx->request_method) :
"tx null",
5988 tx ? bstr_util_strdup_to_c(tx->request_protocol) :
"tx null");
5992 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5997 if (decoder_events == NULL) {
5998 printf(
"no app events: ");
6003 printf(
"HTTP_DECODER_EVENT_METHOD_DELIM_NON_COMPLIANT not set: ");
6008 printf(
"HTTP_DECODER_EVENT_URI_DELIM_NON_COMPLIANT not set: ");
6024 static int HTPParserTest20(
void)
6027 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
6028 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
6029 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
6030 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6031 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
6032 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6033 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
6034 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
6040 memset(&ssn, 0,
sizeof(ssn));
6042 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
6045 f->
proto = IPPROTO_TCP;
6064 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
6066 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
6069 FAIL_IF(tx->request_method_number != HTP_M_GET);
6070 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
6072 FAIL_IF(tx->response_status_number != 0);
6073 FAIL_IF(tx->response_protocol_number != -1);
6083 static int HTPParserTest21(
void)
6086 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
6087 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
6088 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
6089 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6090 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
6091 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6092 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
6093 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
6099 memset(&ssn, 0,
sizeof(ssn));
6101 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
6104 f->
proto = IPPROTO_TCP;
6123 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
6125 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
6128 FAIL_IF(tx->request_method_number != HTP_M_GET);
6129 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
6131 FAIL_IF(tx->response_status_number != 0);
6132 FAIL_IF(tx->response_protocol_number != -1);
6142 static int HTPParserTest22(
void)
6145 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
6146 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
6147 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
6148 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6149 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
6150 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
6151 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6157 memset(&ssn, 0,
sizeof(ssn));
6159 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
6162 f->
proto = IPPROTO_TCP;
6177 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
6179 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
6182 FAIL_IF(tx->request_method_number != HTP_M_GET);
6183 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
6185 FAIL_IF(tx->response_status_number != -0);
6186 FAIL_IF(tx->response_protocol_number != -1);
6196 static int HTPParserTest23(
void)
6199 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
6200 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
6201 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
6202 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6203 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
6204 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
6205 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6211 memset(&ssn, 0,
sizeof(ssn));
6213 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
6216 f->
proto = IPPROTO_TCP;
6231 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
6233 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
6236 FAIL_IF(tx->request_method_number != HTP_M_GET);
6237 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
6239 FAIL_IF(tx->response_status_number != -1);
6240 FAIL_IF(tx->response_protocol_number != -2);
6250 static int HTPParserTest24(
void)
6253 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
6254 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
6255 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
6256 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6257 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
6258 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
6259 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6265 memset(&ssn, 0,
sizeof(ssn));
6267 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
6270 f->
proto = IPPROTO_TCP;
6285 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
6287 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
6290 FAIL_IF(tx->request_method_number != HTP_M_GET);
6291 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
6293 FAIL_IF(tx->response_status_number != -1);
6294 FAIL_IF(tx->response_protocol_number != HTP_PROTOCOL_1_0);
6303 static int HTPParserTest25(
void)
6310 memset(&ssn, 0,
sizeof(ssn));
6315 f->
proto = IPPROTO_TCP;
6318 const char *
str =
"GET / HTTP/1.1\r\nHost: www.google.com\r\nUser-Agent: Suricata/1.0\r\n\r\n";
6320 (uint8_t *)
str, strlen(
str));
6344 str =
"HTTP 1.1 200 OK\r\nServer: Suricata/1.0\r\nContent-Length: 8\r\n\r\nSuricata";
6346 (uint8_t *)
str, strlen(
str));
6380 (uint8_t *)
str, strlen(
str));
6391 (uint8_t *)
str, strlen(
str));
6411 static int HTPParserTest26(
void)
6420 request-body-limit: 1\n\
6421 response-body-limit: 1\n\
6435 uint8_t httpbuf1[] =
"GET /alice.txt HTTP/1.1\r\n\r\n";
6436 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
6437 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\n"
6438 "Content-Type: text/plain\r\n"
6439 "Content-Length: 228\r\n\r\n"
6440 "Alice was beginning to get very tired of sitting by her sister on the bank."
6441 "Alice was beginning to get very tired of sitting by her sister on the bank.";
6442 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
6443 uint8_t httpbuf3[] =
"Alice was beginning to get very tired of sitting by her sister on the bank.\r\n\r\n";
6444 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
6450 memset(&th_v, 0,
sizeof(th_v));
6451 memset(&f, 0,
sizeof(f));
6452 memset(&ssn, 0,
sizeof(ssn));
6459 f.
proto = IPPROTO_TCP;
6480 "(filestore; sid:1; rev:1;)");
6525 AppLayerGetFileState files = HTPGetTxFiles(tx_ptr, STREAM_TOCLIENT);
6547 static int HTPParserTest27(
void)
6550 memset(&cfg, 0,
sizeof(cfg));
6554 uint32_t
len = 1000;
6579 static void HTPParserRegisterTests(
void)
6601 UtRegisterTest(
"HTPParserDecodingTest01", HTPParserDecodingTest01);
6602 UtRegisterTest(
"HTPParserDecodingTest01a", HTPParserDecodingTest01a);
6603 UtRegisterTest(
"HTPParserDecodingTest02", HTPParserDecodingTest02);
6604 UtRegisterTest(
"HTPParserDecodingTest03", HTPParserDecodingTest03);
6605 UtRegisterTest(
"HTPParserDecodingTest04", HTPParserDecodingTest04);
6606 UtRegisterTest(
"HTPParserDecodingTest05", HTPParserDecodingTest05);
6607 UtRegisterTest(
"HTPParserDecodingTest06", HTPParserDecodingTest06);
6608 UtRegisterTest(
"HTPParserDecodingTest07", HTPParserDecodingTest07);
6609 UtRegisterTest(
"HTPParserDecodingTest08", HTPParserDecodingTest08);
6610 UtRegisterTest(
"HTPParserDecodingTest09", HTPParserDecodingTest09);
6612 UtRegisterTest(
"HTPBodyReassemblyTest01", HTPBodyReassemblyTest01);