99 #define HTP_MAX_MESSAGES 512
105 static uint64_t htp_state_memuse = 0;
106 static uint64_t htp_state_memcnt = 0;
116 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST",
118 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE",
120 {
"INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST",
122 {
"INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE",
124 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST",
126 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE",
129 {
"UNABLE_TO_MATCH_RESPONSE_TO_REQUEST",
144 {
"REQUEST_SERVER_PORT_TCP_PORT_MISMATCH",
158 {
"RESPONSE_ABNORMAL_TRANSFER_ENCODING",
201 static int HTTPGetFrameIdByName(
const char *frame_name)
210 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
216 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
217 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
218 static uint64_t HTPStateGetTxCnt(
void *alstate);
220 static void HTPParserRegisterTests(
void);
223 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
225 uint64_t
id = HTPStateGetTxCnt(s);
230 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
243 static const char *HTPLookupPersonalityString(
int p)
245 #define CASE_HTP_PERSONALITY_STRING(p) \
246 case HTP_SERVER_ ## p: return #p
249 CASE_HTP_PERSONALITY_STRING(MINIMAL);
250 CASE_HTP_PERSONALITY_STRING(GENERIC);
251 CASE_HTP_PERSONALITY_STRING(IDS);
252 CASE_HTP_PERSONALITY_STRING(IIS_4_0);
253 CASE_HTP_PERSONALITY_STRING(IIS_5_0);
254 CASE_HTP_PERSONALITY_STRING(IIS_5_1);
255 CASE_HTP_PERSONALITY_STRING(IIS_6_0);
256 CASE_HTP_PERSONALITY_STRING(IIS_7_0);
257 CASE_HTP_PERSONALITY_STRING(IIS_7_5);
258 CASE_HTP_PERSONALITY_STRING(APACHE_2);
272 static int HTPLookupPersonality(
const char *
str)
274 #define IF_HTP_PERSONALITY_NUM(p) \
275 if (strcasecmp(#p, str) == 0) return HTP_SERVER_ ## p
287 if (strcasecmp(
"TOMCAT_6_0",
str) == 0) {
289 "longer supported by libhtp.",
292 }
else if ((strcasecmp(
"APACHE",
str) == 0) ||
293 (strcasecmp(
"APACHE_2_2",
str) == 0))
296 "longer supported by libhtp, failing back to "
297 "Apache2 personality.",
299 return HTP_SERVER_APACHE_2;
306 const uint8_t dir,
const uint8_t e)
316 const uint64_t tx_id = (dir == STREAM_TOSERVER) ?
317 HtpGetActiveRequestTxID(s) : HtpGetActiveResponseTxID(s);
319 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
320 if (tx == NULL && tx_id > 0)
321 tx = HTPStateGetTx(s, tx_id - 1);
336 static void *HTPStateAlloc(
void *orig_state,
AppProto proto_orig)
350 htp_state_memuse +=
sizeof(
HtpState);
351 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
371 if (htud->
tx_data.de_state != NULL) {
397 if (s->
connp != NULL) {
401 uint64_t total_txs = HTPStateGetTxCnt(state);
403 if (s->
conn != NULL) {
404 for (tx_id = 0; tx_id < total_txs; tx_id++) {
405 htp_tx_t *tx = HTPStateGetTx(s, tx_id);
408 HtpTxUserDataFree(s, htud);
409 htp_tx_set_user_data(tx, NULL);
413 htp_connp_destroy_all(s->
connp);
421 htp_state_memuse -=
sizeof(
HtpState);
422 SCLogDebug(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
435 static void HTPStateTransactionFree(
void *state, uint64_t
id)
443 htp_tx_t *tx = HTPStateGetTx(s,
id);
447 HtpTxUserDataFree(s, htud);
448 htp_tx_set_user_data(tx, NULL);
455 tx->request_progress == HTP_REQUEST_COMPLETE &&
456 tx->response_progress == HTP_RESPONSE_COMPLETE)))
458 tx->request_progress = HTP_REQUEST_COMPLETE;
459 tx->response_progress = HTP_RESPONSE_COMPLETE;
497 static void AppLayerHtpNeedMultipartHeader(
void)
515 AppLayerHtpNeedMultipartHeader();
523 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
528 if (
flags & STREAM_TOCLIENT) {
538 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
555 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
556 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
558 uint32_t chunk_len = 0;
560 (content_len_so_far < (uint64_t)body_limit) &&
561 (content_len_so_far + (uint64_t)data_len) > body_limit)
563 chunk_len = body_limit - content_len_so_far;
565 (content_len_so_far < (uint64_t)stream_depth) &&
566 (content_len_so_far + (uint64_t)data_len) > stream_depth)
568 chunk_len = stream_depth - content_len_so_far;
571 return (chunk_len == 0 ? data_len : chunk_len);
618 {
"Request line: URI contains non-compliant delimiter",
620 {
"Request line: non-compliant delimiter between Method and URI",
629 {
"Transfer-encoding has abnormal chunked value",
631 {
"Chunked transfer-encoding on HTTP/0.9 or HTTP/1.0",
634 {
"Invalid response line: invalid response status",
640 {
"Ambiguous response C-L value",
645 #define HTP_ERROR_MAX (sizeof(htp_errors) / sizeof(htp_errors[0]))
646 #define HTP_WARNING_MAX (sizeof(htp_warnings) / sizeof(htp_warnings[0]))
657 static uint8_t HTPHandleWarningGetId(
const char *
msg)
681 static uint8_t HTPHandleErrorGetId(
const char *
msg)
705 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
707 if (s == NULL || s->
conn == NULL ||
708 s->
conn->messages == NULL) {
712 size_t size = htp_list_size(s->
conn->messages);
727 htp_log_t *log = htp_list_get(s->
conn->messages,
msg);
732 htp_tx_t *tx = log->tx;
738 uint8_t
id = HTPHandleErrorGetId(log->msg);
740 id = HTPHandleWarningGetId(log->msg);
746 HTPSetEvent(s, htud, dir,
id);
753 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s, htp_tx_t *tx)
756 BUG_ON(s == NULL || tx == NULL);
758 if (tx->flags & ( HTP_REQUEST_INVALID_T_E|HTP_REQUEST_INVALID_C_L|
759 HTP_HOST_MISSING|HTP_HOST_AMBIGUOUS|HTP_HOSTU_INVALID|
766 if (tx->flags & HTP_REQUEST_INVALID_T_E)
767 HTPSetEvent(s, htud, STREAM_TOSERVER,
769 if (tx->flags & HTP_REQUEST_INVALID_C_L)
770 HTPSetEvent(s, htud, STREAM_TOSERVER,
772 if (tx->flags & HTP_HOST_MISSING)
773 HTPSetEvent(s, htud, STREAM_TOSERVER,
775 if (tx->flags & HTP_HOST_AMBIGUOUS)
776 HTPSetEvent(s, htud, STREAM_TOSERVER,
778 if (tx->flags & HTP_HOSTU_INVALID)
779 HTPSetEvent(s, htud, STREAM_TOSERVER,
781 if (tx->flags & HTP_HOSTH_INVALID)
782 HTPSetEvent(s, htud, STREAM_TOSERVER,
785 if (tx->request_auth_type == HTP_AUTH_UNRECOGNIZED) {
789 HTPSetEvent(s, htud, STREAM_TOSERVER,
792 if (tx->is_protocol_0_9 && tx->request_method_number == HTP_M_UNKNOWN &&
793 (tx->request_protocol_number == HTP_PROTOCOL_INVALID ||
794 tx->request_protocol_number == HTP_PROTOCOL_UNKNOWN)) {
798 HTPSetEvent(s, htud, STREAM_TOSERVER,
809 htp_cfg_t *htp = cfglist.
cfg;
810 void *user_data = NULL;
825 if (user_data != NULL) {
826 htp_cfg_rec = user_data;
827 htp = htp_cfg_rec->
cfg;
830 SCLogDebug(
"Using default HTP config: %p", htp);
834 #ifdef DEBUG_VALIDATION
841 hstate->
connp = htp_connp_create(htp);
842 if (hstate->
connp == NULL) {
846 hstate->
conn = htp_connp_get_connection(hstate->
connp);
848 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
849 hstate->
cfg = htp_cfg_rec;
854 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
876 StreamSlice stream_slice,
void *local_data)
886 if (NULL == hstate->
conn) {
887 if (Setup(f, hstate) != 0) {
892 hstate->
slice = &stream_slice;
894 const uint8_t *input = StreamSliceGetData(&stream_slice);
895 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
900 const int r = htp_connp_req_data(hstate->
connp, &
ts, input, input_len);
902 case HTP_STREAM_ERROR:
908 HTPHandleError(hstate, STREAM_TOSERVER);
915 htp_connp_req_close(hstate->
connp, &
ts);
917 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
921 hstate->
slice = NULL;
943 StreamSlice stream_slice,
void *local_data)
949 const uint8_t *input = StreamSliceGetData(&stream_slice);
950 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
956 if (NULL == hstate->
conn) {
957 if (Setup(f, hstate) != 0) {
962 hstate->
slice = &stream_slice;
968 const int r = htp_connp_res_data(hstate->
connp, &
ts, input, input_len);
970 case HTP_STREAM_ERROR:
973 case HTP_STREAM_TUNNEL:
974 tx = htp_connp_get_out_tx(hstate->
connp);
975 if (tx != NULL && tx->response_status_number == 101) {
977 (htp_header_t *)htp_table_get_c(tx->response_headers,
"Upgrade");
978 if (h == NULL || bstr_cmp_c(h->value,
"h2c") != 0) {
986 if (tx->request_port_number != -1) {
987 dp = (uint16_t)tx->request_port_number;
989 consumed = htp_connp_res_data_consumed(hstate->
connp);
990 hstate->
slice = NULL;
992 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
997 if (consumed > 0 && consumed < input_len) {
1006 HTPHandleError(hstate, STREAM_TOCLIENT);
1013 htp_connp_close(hstate->
connp, &
ts);
1018 hstate->
slice = NULL;
1029 static int HTTPParseContentDispositionHeader(uint8_t *name,
size_t name_len,
1030 uint8_t *data,
size_t len, uint8_t **retptr,
size_t *retlen)
1033 printf(
"DATA START: \n");
1035 printf(
"DATA END: \n");
1040 for (x = 0; x <
len; x++) {
1041 if (!(isspace(data[x])))
1048 uint8_t *line = data+x;
1049 size_t line_len =
len-x;
1052 printf(
"LINE START: \n");
1054 printf(
"LINE END: \n");
1056 for (x = 0 ; x < line_len; x++) {
1058 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
1062 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
1063 uint8_t *token = line +
offset;
1064 size_t token_len = x -
offset;
1066 if ((x + 1) == line_len) {
1077 printf(
"TOKEN START: \n");
1079 printf(
"TOKEN END: \n");
1081 if (token_len > name_len) {
1082 if (name == NULL || SCMemcmpLowercase(name, token, name_len) == 0) {
1083 uint8_t *value = token + name_len;
1084 size_t value_len = token_len - name_len;
1086 if (value[0] ==
'\"') {
1090 if (value[value_len-1] ==
'\"') {
1094 printf(
"VALUE START: \n");
1096 printf(
"VALUE END: \n");
1099 *retlen = value_len;
1113 static int HTTPParseContentTypeHeader(uint8_t *name,
size_t name_len,
1114 uint8_t *data,
size_t len, uint8_t **retptr,
size_t *retlen)
1118 printf(
"DATA START: \n");
1120 printf(
"DATA END: \n");
1125 for (x = 0; x <
len; x++) {
1126 if (!(isspace(data[x])))
1134 uint8_t *line = data+x;
1135 size_t line_len =
len-x;
1138 printf(
"LINE START: \n");
1140 printf(
"LINE END: \n");
1142 for (x = 0 ; x < line_len; x++) {
1144 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
1148 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
1149 uint8_t *token = line +
offset;
1150 size_t token_len = x -
offset;
1152 if ((x + 1) == line_len) {
1163 printf(
"TOKEN START: \n");
1165 printf(
"TOKEN END: \n");
1167 if (token_len > name_len) {
1168 if (name == NULL || SCMemcmpLowercase(name, token, name_len) == 0) {
1169 uint8_t *value = token + name_len;
1170 size_t value_len = token_len - name_len;
1172 if (value[0] ==
'\"') {
1176 if (value[value_len-1] ==
'\"') {
1180 printf(
"VALUE START: \n");
1182 printf(
"VALUE END: \n");
1185 *retlen = value_len;
1209 static int HtpRequestBodySetupMultipart(htp_tx_t *tx,
HtpTxUserData *htud)
1211 htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->request_headers,
1213 if (h != NULL && bstr_len(h->value) > 0) {
1214 uint8_t *boundary = NULL;
1215 size_t boundary_len = 0;
1217 int r = HTTPParseContentTypeHeader((uint8_t *)
"boundary=", 9,
1218 (uint8_t *) bstr_ptr(h->value), bstr_len(h->value),
1219 &boundary, &boundary_len);
1222 printf(
"BOUNDARY START: \n");
1224 printf(
"BOUNDARY END: \n");
1232 memcpy(htud->
boundary, boundary, boundary_len);
1246 #define C_D_HDR "content-disposition:"
1247 #define C_D_HDR_LEN 20
1248 #define C_T_HDR "content-type:"
1249 #define C_T_HDR_LEN 13
1251 static void HtpRequestBodyMultipartParseHeader(
HtpState *hstate,
1253 uint8_t *header, uint32_t header_len,
1254 uint8_t **filename, uint16_t *filename_len,
1255 uint8_t **filetype, uint16_t *filetype_len)
1263 printf(
"HEADER START: \n");
1265 printf(
"HEADER END: \n");
1268 while (header_len > 0) {
1269 uint8_t *next_line =
Bs2bmSearch(header, header_len, (uint8_t *)
"\r\n", 2);
1270 uint8_t *line = header;
1273 if (next_line == NULL) {
1274 line_len = header_len;
1276 line_len = next_line - header;
1278 uint8_t *sc = (uint8_t *)memchr(line,
':', line_len);
1280 HTPSetEvent(hstate, htud, STREAM_TOSERVER,
1284 }
else if (line_len > 0 && sc == &line[line_len - 1]) {
1285 HTPSetEvent(hstate, htud, STREAM_TOSERVER,
1289 printf(
"LINE START: \n");
1291 printf(
"LINE END: \n");
1299 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1300 value, value_len, &fn, &fn_len);
1307 (void)HTTPParseContentTypeHeader(NULL, 0,
1308 value, value_len, &ft, &ft_len);
1312 if (next_line == NULL) {
1316 header_len -= ((next_line + 2) - header);
1317 header = next_line + 2;
1320 if (fn_len > USHRT_MAX)
1322 if (ft_len > USHRT_MAX)
1326 *filename_len = (uint16_t)fn_len;
1328 *filetype_len = (uint16_t)ft_len;
1339 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1342 chunks_buffer, chunks_buffer_len,
1346 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1349 if (tx && tx->
tx_data.de_state) {
1350 if (dir == STREAM_TOSERVER) {
1351 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1353 }
else if (STREAM_TOCLIENT) {
1354 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1363 static void HtpRequestBodySetupBoundary(
HtpTxUserData *htud,
1364 uint8_t *boundary, uint32_t boundary_len)
1366 memset(boundary,
'-', boundary_len);
1371 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len)
1375 uint16_t expected_boundary_len = htud->
boundary_len + 2;
1376 uint16_t expected_boundary_end_len = htud->
boundary_len + 4;
1377 int tx_progress = 0;
1380 printf(
"CHUNK START: \n");
1382 printf(
"CHUNK END: \n");
1385 HtpRequestBodySetupBoundary(htud, boundary, htud->
boundary_len + 4);
1388 const uint8_t *header_start =
Bs2bmSearch(chunks_buffer, chunks_buffer_len,
1389 boundary, expected_boundary_len);
1391 const uint8_t *form_end = NULL;
1393 const uint8_t *header_end = NULL;
1394 if (header_start != NULL) {
1395 header_end =
Bs2bmSearch(header_start, chunks_buffer_len - (header_start - chunks_buffer),
1396 (uint8_t *)
"\r\n\r\n", 4);
1397 form_end =
Bs2bmSearch(header_start, chunks_buffer_len - (header_start - chunks_buffer),
1398 boundary, expected_boundary_end_len);
1401 SCLogDebug(
"header_start %p, header_end %p, form_end %p", header_start,
1402 header_end, form_end);
1409 if (header_start != NULL || (tx_progress > HTP_REQUEST_BODY)) {
1412 const uint8_t *filedata = chunks_buffer;
1413 uint32_t filedata_len = 0;
1416 if (header_start != NULL) {
1417 if (header_start == filedata + 2) {
1419 SCLogDebug(
"last chunk had all data, but not the boundary");
1421 }
else if (header_start > filedata + 2) {
1422 SCLogDebug(
"some data from last file before the boundary");
1424 filedata_len = header_start - filedata - 2;
1429 if (tx_progress > HTP_REQUEST_BODY) {
1430 filedata_len = chunks_buffer_len;
1434 if (filedata_len > chunks_buffer_len) {
1435 HTPSetEvent(hstate, htud, STREAM_TOSERVER,
1440 printf(
"FILEDATA (final chunk) START: \n");
1442 printf(
"FILEDATA (final chunk) END: \n");
1445 if (
HTPFileClose(hstate, htud, filedata, filedata_len,
flags, STREAM_TOSERVER) ==
1455 SCLogDebug(
"not yet at the end of the file");
1457 if (chunks_buffer_len > expected_boundary_end_len) {
1458 const uint8_t *filedata = chunks_buffer;
1459 uint32_t filedata_len = chunks_buffer_len - expected_boundary_len;
1460 for (; filedata_len < chunks_buffer_len; filedata_len++) {
1462 if (chunks_buffer[filedata_len] ==
'\r') {
1463 if (filedata_len + 1 == chunks_buffer_len ||
1464 chunks_buffer[filedata_len + 1] ==
'\n') {
1471 printf(
"FILEDATA (part) START: \n");
1473 printf(
"FILEDATA (part) END: \n");
1478 hstate, htud, filedata, filedata_len, STREAM_TOSERVER);
1481 }
else if (result == -2) {
1489 SCLogDebug(
"chunk too small to already process in part");
1496 while (header_start != NULL && header_end != NULL &&
1497 header_end != form_end &&
1498 header_start < (chunks_buffer + chunks_buffer_len) &&
1499 header_end < (chunks_buffer + chunks_buffer_len) &&
1500 header_start < header_end)
1502 uint8_t *filename = NULL;
1503 uint16_t filename_len = 0;
1504 uint8_t *filetype = NULL;
1505 uint16_t filetype_len = 0;
1507 uint32_t header_len = header_end - header_start;
1509 uint8_t *header = (uint8_t *)header_start;
1512 if (expected_boundary_len == header_len) {
1514 }
else if ((uint32_t)(expected_boundary_len + 2) <= header_len) {
1515 header_len -= (expected_boundary_len + 2);
1516 header = (uint8_t *)header_start + (expected_boundary_len + 2);
1519 HtpRequestBodyMultipartParseHeader(hstate, htud, header, header_len,
1520 &filename, &filename_len, &filetype, &filetype_len);
1522 if (filename != NULL) {
1523 const uint8_t *filedata = NULL;
1524 uint32_t filedata_len = 0;
1535 if (form_end != NULL) {
1538 filedata = header_end + 4;
1539 if (form_end == filedata) {
1540 HTPSetEvent(hstate, htud, STREAM_TOSERVER,
1543 }
else if (form_end < filedata) {
1544 HTPSetEvent(hstate, htud, STREAM_TOSERVER,
1549 filedata_len = form_end - (header_end + 4 + 2);
1550 SCLogDebug(
"filedata_len %"PRIuMAX, (uintmax_t)filedata_len);
1553 uint8_t *header_next =
Bs2bmSearch(filedata, filedata_len,
1554 boundary, expected_boundary_len);
1555 if (header_next != NULL) {
1556 filedata_len -= (form_end - header_next);
1559 if (filedata_len > chunks_buffer_len) {
1560 HTPSetEvent(hstate, htud, STREAM_TOSERVER,
1564 SCLogDebug(
"filedata_len %"PRIuMAX, (uintmax_t)filedata_len);
1566 printf(
"FILEDATA START: \n");
1568 printf(
"FILEDATA END: \n");
1571 result =
HTPFileOpen(hstate, htud, filename, filename_len, filedata, filedata_len,
1572 HtpGetActiveRequestTxID(hstate), STREAM_TOSERVER);
1575 }
else if (result == -2) {
1578 if (
HTPFileClose(hstate, htud, NULL, 0, 0, STREAM_TOSERVER) == -1) {
1582 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1587 SCLogDebug(
"chunk doesn't contain form end");
1589 filedata = header_end + 4;
1590 filedata_len = chunks_buffer_len - (filedata - chunks_buffer);
1591 SCLogDebug(
"filedata_len %u (chunks_buffer_len %u)", filedata_len, chunks_buffer_len);
1593 if (filedata_len > chunks_buffer_len) {
1594 HTPSetEvent(hstate, htud, STREAM_TOSERVER,
1600 printf(
"FILEDATA START: \n");
1602 printf(
"FILEDATA END: \n");
1606 uint8_t *header_next =
Bs2bmSearch(filedata, filedata_len,
1607 boundary, expected_boundary_len);
1609 if (header_next == NULL) {
1612 uint32_t
offset = (header_end + 4) - chunks_buffer;
1616 if (filedata_len >= (uint32_t)(expected_boundary_len + 2)) {
1617 filedata_len -= (expected_boundary_len + 2 - 1);
1619 for (
size_t nb = 0; nb < (size_t)expected_boundary_len + 1; nb++) {
1620 if (filedata[filedata_len] ==
'\r') {
1621 if (nb == expected_boundary_len ||
1622 filedata[filedata_len + 1] ==
'\n') {
1628 SCLogDebug(
"opening file with partial data");
1633 result =
HTPFileOpen(hstate, htud, filename, filename_len, filedata,
1634 filedata_len, HtpGetActiveRequestTxID(hstate), STREAM_TOSERVER);
1637 }
else if (result == -2) {
1640 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1644 }
else if (header_next - filedata > 2) {
1645 filedata_len = header_next - filedata - 2;
1648 result =
HTPFileOpen(hstate, htud, filename, filename_len, filedata,
1649 filedata_len, HtpGetActiveRequestTxID(hstate), STREAM_TOSERVER);
1652 }
else if (result == -2) {
1655 if (
HTPFileClose(hstate, htud, NULL, 0, 0, STREAM_TOSERVER) == -1) {
1659 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1667 SCLogDebug(
"header_start %p, header_end %p, form_end %p",
1668 header_start, header_end, form_end);
1671 uint32_t cursizeread = header_end - chunks_buffer;
1673 chunks_buffer_len - (cursizeread + 4),
1674 boundary, expected_boundary_len);
1675 if (header_start != NULL) {
1677 chunks_buffer_len - (cursizeread + 4),
1678 (uint8_t *)
"\r\n\r\n", 4);
1685 if (chunks_buffer_len > expected_boundary_end_len) {
1686 uint32_t move = chunks_buffer_len - expected_boundary_end_len + 1;
1689 SCLogDebug(
"form not ready, file not set, parsing non-file "
1690 "record: moved %u", move);
1703 htp_tx_t *tx, uint8_t *data, uint32_t data_len)
1710 uint8_t *filename = NULL;
1711 size_t filename_len = 0;
1714 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1715 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1716 filename_len = bstr_len(tx->parsed_uri->path);
1719 if (filename != NULL) {
1725 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1726 HtpGetActiveRequestTxID(hstate), STREAM_TOSERVER);
1729 }
else if (result == -2) {
1732 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1746 }
else if (result == -2) {
1759 htp_tx_t *tx, uint8_t *data, uint32_t data_len)
1772 uint8_t *filename = NULL;
1773 size_t filename_len = 0;
1776 htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->response_headers,
1777 "Content-Disposition");
1778 if (h != NULL && bstr_len(h->value) > 0) {
1780 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1781 (uint8_t *) bstr_ptr(h->value), bstr_len(h->value), &filename, &filename_len);
1785 if (filename == NULL) {
1787 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1788 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1789 filename_len = bstr_len(tx->parsed_uri->path);
1793 if (filename != NULL) {
1795 htp_header_t *h_content_range = htp_table_get_c(tx->response_headers,
"content-range");
1801 if (h_content_range != NULL) {
1803 data_len, HtpGetActiveResponseTxID(hstate), h_content_range->value, htud);
1805 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1806 HtpGetActiveResponseTxID(hstate), STREAM_TOCLIENT);
1811 }
else if (result == -2) {
1814 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1827 }
else if (result == -2) {
1845 static int HTPCallbackRequestBodyData(htp_tx_data_t *d)
1856 printf(
"HTPBODY START: \n");
1858 printf(
"HTPBODY END: \n");
1861 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1862 if (hstate == NULL) {
1866 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1867 "%"PRIu32
"", hstate, d, d->data, (uint32_t)d->len);
1870 if (tx_ud == NULL) {
1878 if (d->tx->request_method_number == HTP_M_POST) {
1880 int r = HtpRequestBodySetupMultipart(d->tx, tx_ud);
1883 }
else if (r == 0) {
1887 }
else if (d->tx->request_method_number == HTP_M_PUT) {
1910 const uint8_t *chunks_buffer = NULL;
1911 uint32_t chunks_buffer_len = 0;
1919 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1920 if (chunks_buffer == NULL) {
1924 printf(
"REASSCHUNK START: \n");
1926 printf(
"REASSCHUNK END: \n");
1929 HtpRequestBodyHandleMultipart(hstate, tx_ud, d->tx, chunks_buffer, chunks_buffer_len);
1933 HtpRequestBodyHandlePOSTorPUT(hstate, tx_ud, d->tx, (uint8_t *)d->data,
len);
1938 SCLogDebug(
"closing file that was being stored");
1945 if (hstate->
conn != NULL) {
1946 SCLogDebug(
"checking body size %"PRIu64
" against inspect limit %u (cur %"PRIu64
", last %"PRIu64
")",
1960 const uint32_t data_size = (uint32_t)(
1981 static int HTPCallbackResponseBodyData(htp_tx_data_t *d)
1991 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1992 if (hstate == NULL) {
1996 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1997 "%"PRIu32
"", hstate, d, d->data, (uint32_t)d->len);
2000 if (tx_ud == NULL) {
2026 HtpResponseBodyHandle(hstate, tx_ud, d->tx, (uint8_t *)d->data,
len);
2029 SCLogDebug(
"closing file that was being stored");
2035 if (hstate->
conn != NULL) {
2036 SCLogDebug(
"checking body size %"PRIu64
" against inspect limit %u (cur %"PRIu64
", last %"PRIu64
")",
2049 const uint32_t data_size = (uint32_t)((uint64_t)hstate->
conn->out_data_counter -
2073 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
2074 htp_state_memcnt, htp_state_memuse);
2094 htp_config_destroy(cfglist.
cfg);
2095 while (nextrec != NULL) {
2097 nextrec = nextrec->
next;
2099 htp_config_destroy(htprec->
cfg);
2105 static int HTPCallbackRequestHasTrailer(htp_tx_t *tx)
2114 static int HTPCallbackResponseHasTrailer(htp_tx_t *tx)
2127 static int HTPCallbackRequestStart(htp_tx_t *tx)
2129 HtpState *hstate = htp_connp_get_user_data(tx->connp);
2130 if (hstate == NULL) {
2134 uint64_t consumed = hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
2135 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
2136 (uint64_t)hstate->
conn->in_data_counter);
2153 if (tx_ud == NULL) {
2158 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
2159 htp_tx_set_user_data(tx, tx_ud);
2168 static int HTPCallbackResponseStart(htp_tx_t *tx)
2170 HtpState *hstate = htp_connp_get_user_data(tx->connp);
2171 if (hstate == NULL) {
2175 uint64_t consumed = hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
2176 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
2177 (uint64_t)hstate->
conn->out_data_counter);
2192 if (tx_ud == NULL) {
2199 htp_tx_set_user_data(tx, tx_ud);
2210 static int HTPCallbackRequestComplete(htp_tx_t *tx)
2218 HtpState *hstate = htp_connp_get_user_data(tx->connp);
2219 if (hstate == NULL) {
2223 const uint64_t abs_right_edge =
2224 hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
2232 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
2234 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
2236 frame->
len = (int64_t)request_size;
2242 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
2247 HTPErrorCheckTxRequestFlags(hstate, tx);
2252 SCLogDebug(
"closing file that was being stored");
2253 (void)
HTPFileClose(hstate, htud, NULL, 0, 0, STREAM_TOSERVER);
2255 if (abs_right_edge < (uint64_t)UINT32_MAX) {
2257 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
2275 static int HTPCallbackResponseComplete(htp_tx_t *tx)
2279 HtpState *hstate = htp_connp_get_user_data(tx->connp);
2280 if (hstate == NULL) {
2287 const uint64_t abs_right_edge =
2288 hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
2295 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
2297 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
2299 frame->
len = (int64_t)response_size;
2307 SCLogDebug(
"closing file that was being stored");
2308 (void)
HTPFileClose(hstate, htud, NULL, 0, 0, STREAM_TOCLIENT);
2318 if (tx->request_method_number == HTP_M_CONNECT) {
2321 if ((tx->response_status_number >= 200) &&
2322 (tx->response_status_number < 300) &&
2325 if (tx->request_port_number != -1) {
2326 dp = (uint16_t)tx->request_port_number;
2333 tx->request_progress = HTP_REQUEST_COMPLETE;
2334 tx->response_progress = HTP_RESPONSE_COMPLETE;
2342 static int HTPCallbackRequestLine(htp_tx_t *tx)
2345 bstr *request_uri_normalized;
2346 HtpState *hstate = htp_connp_get_user_data(tx->connp);
2350 if (request_uri_normalized == NULL)
2353 tx_ud = htp_tx_get_user_data(tx);
2355 bstr_free(request_uri_normalized);
2363 HTPErrorCheckTxRequestFlags(hstate, tx);
2368 static int HTPCallbackDoubleDecodeUriPart(htp_tx_t *tx, bstr *part)
2374 size_t prevlen = bstr_len(part);
2375 htp_status_t res = htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, part, &
flags);
2377 if (res == HTP_OK && prevlen > bstr_len(part)) {
2381 HtpState *s = htp_connp_get_user_data(tx->connp);
2384 HTPSetEvent(s, htud, STREAM_TOSERVER,
2391 static int HTPCallbackDoubleDecodeQuery(htp_tx_t *tx)
2393 if (tx->parsed_uri == NULL)
2396 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->query);
2399 static int HTPCallbackDoubleDecodePath(htp_tx_t *tx)
2401 if (tx->parsed_uri == NULL)
2404 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->path);
2407 static int HTPCallbackRequestHeaderData(htp_tx_data_t *tx_data)
2410 if (tx_data->len == 0 || tx_data->tx == NULL)
2414 if (tx_ud == NULL) {
2426 tx_data->data, tx_data->len);
2429 if (tx_data->tx && tx_data->tx->flags) {
2430 HtpState *hstate = htp_connp_get_user_data(tx_data->tx->connp);
2431 HTPErrorCheckTxRequestFlags(hstate, tx_data->tx);
2436 static int HTPCallbackResponseHeaderData(htp_tx_data_t *tx_data)
2439 if (tx_data->len == 0 || tx_data->tx == NULL)
2443 if (tx_ud == NULL) {
2455 tx_data->data, tx_data->len);
2464 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
2481 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2482 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2483 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2484 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2486 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
2487 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
2489 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
2490 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
2492 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
2493 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
2495 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
2496 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
2498 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
2501 htp_config_set_plusspace_decode(cfg_prec->
cfg, HTP_DECODER_URLENCODED, 0);
2503 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
2504 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2508 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2509 htp_config_set_lzma_memlimit(cfg_prec->
cfg,
2512 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2513 htp_config_set_compression_bomb_limit(cfg_prec->
cfg,
2516 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2525 htp_config_set_field_limits(cfg_prec->
cfg,
2534 static int RandomGetWrap(
void)
2540 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
2542 return r % RAND_MAX;
2551 static void HTPConfigSetDefaultsPhase2(
const char *name,
HTPCfgRec *cfg_prec)
2557 long int r = RandomGetWrap();
2559 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2561 r = RandomGetWrap();
2563 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2564 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
2565 " %u and 'request-body-inspect-window' set to %u after"
2569 r = RandomGetWrap();
2571 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2573 r = RandomGetWrap();
2575 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2577 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2578 " %u and 'response-body-inspect-window' set to %u after"
2583 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2590 if (cfg_prec == NULL || s == NULL || tree == NULL)
2598 if (strcasecmp(
"address", p->
name) == 0) {
2606 if (strchr(pval->
val,
':') != NULL) {
2607 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2611 "add ipv6 server %s, ignoring",
2615 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2619 "to add ipv4 server %s, ignoring",
2625 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2627 int personality = HTPLookupPersonality(p->
val);
2631 if (personality >= 0) {
2634 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) == HTP_ERROR){
2636 "personality \"%s\", ignoring",
2640 HTPLookupPersonalityString(personality));
2646 htp_config_set_convert_lowercase(cfg_prec->
cfg, HTP_DECODER_URL_PATH, 0);
2654 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2655 strcasecmp(
"request_body_limit", p->
name) == 0) {
2657 SCLogError(
"Error parsing request-body-limit "
2658 "from conf file - %s. Killing engine",
2663 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2665 SCLogError(
"Error parsing response-body-limit "
2666 "from conf file - %s. Killing engine",
2671 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2673 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2674 "from conf file - %s. Killing engine",
2679 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2681 SCLogError(
"Error parsing request-body-inspect-window "
2682 "from conf file - %s. Killing engine",
2687 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2689 htp_config_register_request_line(cfg_prec->
cfg,
2690 HTPCallbackDoubleDecodeQuery);
2693 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2695 htp_config_register_request_line(cfg_prec->
cfg,
2696 HTPCallbackDoubleDecodePath);
2699 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2701 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2702 "from conf file - %s. Killing engine",
2707 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2709 SCLogError(
"Error parsing response-body-inspect-window "
2710 "from conf file - %s. Killing engine",
2715 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2718 SCLogError(
"Error parsing response-body-inspect-window "
2719 "from conf file - %s. Killing engine",
2723 #ifdef HAVE_HTP_CONFIG_SET_RESPONSE_DECOMPRESSION_LAYER_LIMIT
2724 htp_config_set_response_decompression_layer_limit(cfg_prec->
cfg, value);
2726 SCLogWarning(
"can't set response-body-decompress-layer-limit "
2727 "to %u, libhtp version too old",
2730 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2731 htp_config_set_backslash_convert_slashes(cfg_prec->
cfg,
2732 HTP_DECODER_URL_PATH,
2734 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2735 if (strlen(p->
val) == 1) {
2736 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg,
2737 HTP_DECODER_URL_PATH,
2741 "for libhtp param path-bestfit-replacement-char");
2743 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2744 htp_config_set_convert_lowercase(cfg_prec->
cfg,
2745 HTP_DECODER_URL_PATH,
2747 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2748 htp_config_set_nul_encoded_terminates(cfg_prec->
cfg,
2749 HTP_DECODER_URL_PATH,
2751 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2752 htp_config_set_nul_raw_terminates(cfg_prec->
cfg,
2753 HTP_DECODER_URL_PATH,
2755 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2756 htp_config_set_path_separators_compress(cfg_prec->
cfg,
2757 HTP_DECODER_URL_PATH,
2759 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2760 htp_config_set_path_separators_decode(cfg_prec->
cfg,
2761 HTP_DECODER_URL_PATH,
2763 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2764 htp_config_set_u_encoding_decode(cfg_prec->
cfg,
2765 HTP_DECODER_URL_PATH,
2767 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2768 enum htp_url_encoding_handling_t handling;
2769 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2770 handling = HTP_URL_DECODE_PRESERVE_PERCENT;
2771 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2772 handling = HTP_URL_DECODE_REMOVE_PERCENT;
2773 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2774 handling = HTP_URL_DECODE_PROCESS_INVALID;
2777 "for libhtp param path-url-encoding-invalid-handling");
2780 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg,
2781 HTP_DECODER_URL_PATH,
2783 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2784 htp_config_set_utf8_convert_bestfit(cfg_prec->
cfg,
2785 HTP_DECODER_URL_PATH,
2787 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2791 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2792 htp_config_set_plusspace_decode(cfg_prec->
cfg,
2793 HTP_DECODER_URLENCODED,
2795 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2799 "from conf file - %s. Killing engine",
2805 "from conf file cannot be 0. Killing engine");
2808 htp_config_set_field_limits(cfg_prec->
cfg,
2811 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2812 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2815 FatalError(
"failed to parse 'lzma-memlimit' "
2816 "from conf file - %s.",
2821 "from conf file cannot be 0.");
2824 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2825 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2827 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2828 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2830 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2835 "from conf file - %s.",
2838 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2839 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2842 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2843 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2846 FatalError(
"failed to parse 'compression-bomb-limit' "
2847 "from conf file - %s.",
2852 "from conf file cannot be 0.");
2855 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2856 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2858 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2859 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2863 FatalError(
"failed to parse 'decompression-time-limit' "
2864 "from conf file - %s.",
2867 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2868 htp_config_set_compression_time_limit(cfg_prec->
cfg, (
size_t)limit);
2870 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2874 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2877 (
const char *)p->
val, 0, 100) < 0) {
2879 "-inspection-range setting from conf file - \"%s\"."
2880 " It should be a valid integer less than or equal to 100."
2886 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2892 if (strcmp(
"auto", p->
val) != 0) {
2901 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2905 if (strcasecmp(
"enabled", pval->
name) == 0) {
2908 SCLogWarning(
"Flash decompression is deprecated and will be removed in "
2909 "Suricata 8; see ticket #6179");
2915 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2916 if (strcasecmp(
"no", pval->
val) == 0) {
2918 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2920 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2922 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2926 "swf-decompression.type: %s - "
2931 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2933 SCLogError(
"Error parsing swf-decompression.compression-depth "
2934 "from conf file - %s. Killing engine",
2938 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2940 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2941 "from conf file - %s. Killing engine",
2951 "default config: %s",
2963 cfglist.
next = NULL;
2970 if (NULL == cfgtree)
2974 cfglist.
cfg = htp_config_create();
2975 if (NULL == cfglist.
cfg) {
2976 FatalError(
"Failed to create HTP default config");
2979 HTPConfigSetDefaultsPhase1(&cfglist);
2980 if (
ConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2981 HTPConfigParseParameters(&cfglist,
ConfGetNode(
"libhtp.default-config"),
2984 HTPConfigParseParameters(&cfglist,
ConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), cfgtree);
2986 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2992 if (server_config == NULL) {
2993 server_config =
ConfGetNode(
"libhtp.server-config");
2994 if (server_config == NULL) {
2995 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2999 SCLogDebug(
"LIBHTP Configuring %p", server_config);
3017 memset(htprec, 0x00,
sizeof(*htprec));
3019 cfglist.
next = htprec;
3022 cfglist.
next->
cfg = htp_config_create();
3023 if (NULL == cfglist.
next->
cfg) {
3024 FatalError(
"Failed to create HTP server config");
3027 HTPConfigSetDefaultsPhase1(htprec);
3028 HTPConfigParseParameters(htprec, s, cfgtree);
3029 HTPConfigSetDefaultsPhase2(s->
name, htprec);
3039 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
3050 static AppLayerGetFileState HTPGetTxFiles(
void *state,
void *txv, uint8_t direction)
3052 AppLayerGetFileState files = { .fc = NULL, .cfg = &
htp_sbcfg };
3053 htp_tx_t *tx = (htp_tx_t *)txv;
3056 if (direction & STREAM_TOCLIENT) {
3065 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
3067 if (direction & STREAM_TOSERVER)
3068 return ((htp_tx_t *)tx)->request_progress;
3070 return ((htp_tx_t *)tx)->response_progress;
3073 static uint64_t HTPStateGetTxCnt(
void *alstate)
3077 if (http_state != NULL && http_state->
conn != NULL) {
3078 const int64_t size = (int64_t)htp_list_size(http_state->
conn->transactions);
3082 return (uint64_t)size;
3088 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
3092 if (http_state != NULL && http_state->
conn != NULL)
3093 return htp_list_get(http_state->
conn->transactions, tx_id);
3102 if (http_state != NULL && http_state->
conn != NULL) {
3103 size_t txid = htp_list_array_size(http_state->
conn->transactions);
3105 return htp_list_get(http_state->
conn->transactions, txid - 1);
3111 static int HTPStateGetEventInfo(
const char *event_name,
3112 int *event_id, AppLayerEventType *event_type)
3115 if (*event_id == -1) {
3117 "http's enum map table.",
3123 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
3128 static int HTPStateGetEventInfoById(
int event_id,
const char **event_name,
3129 AppLayerEventType *event_type)
3132 if (*event_name == NULL) {
3134 "http's enum map table.",
3140 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
3147 htp_tx_t *tx = (htp_tx_t *)vtx;
3155 static AppLayerStateData *HTPGetStateData(
void *vstate)
3161 static int HTPRegisterPatternsForProtocolDetection(
void)
3163 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
3164 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
3165 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
3166 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
3167 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
3168 const char *spacings[] = {
"|20|",
"|09|", NULL };
3169 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
3174 int register_result;
3175 char method_buffer[32] =
"";
3178 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
3179 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
3182 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
3189 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
3190 if (register_result < 0) {
3197 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
3199 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
3201 if (register_result < 0) {
3217 const char *proto_name =
"http";
3222 if (HTPRegisterPatternsForProtocolDetection() < 0)
3225 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
3240 ALPROTO_HTTP1, HTP_REQUEST_COMPLETE, HTP_RESPONSE_COMPLETE);
3252 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
3254 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
3260 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
3263 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
3267 SCLogInfo(
"Parsed disabled for %s protocol. Protocol detection"
3268 "still on.", proto_name);
3284 cfglist_backup = cfglist;
3291 cfglist = cfglist_backup;
3298 static int HTPParserTest01(
void)
3300 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3302 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3305 memset(&ssn, 0,
sizeof(ssn));
3313 f->
proto = IPPROTO_TCP;
3319 for (u = 0; u < httplen1; u++) {
3323 flags = STREAM_TOSERVER|STREAM_START;
3324 else if (u == (httplen1 - 1))
3325 flags = STREAM_TOSERVER|STREAM_EOF;
3327 flags = STREAM_TOSERVER;
3336 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3339 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3342 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
3343 FAIL_IF(tx->request_method_number != HTP_M_POST);
3344 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
3353 static int HTPParserTest01b(
void)
3355 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
3357 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3360 memset(&ssn, 0,
sizeof(ssn));
3368 f->
proto = IPPROTO_TCP;
3373 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
3380 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3383 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3386 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
3387 FAIL_IF(tx->request_method_number != HTP_M_POST);
3388 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
3397 static int HTPParserTest01c(
void)
3399 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
3401 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3404 memset(&ssn, 0,
sizeof(ssn));
3412 f->
proto = IPPROTO_TCP;
3418 for (u = 0; u < httplen1; u++) {
3422 flags = STREAM_TOSERVER|STREAM_START;
3423 else if (u == (httplen1 - 1))
3424 flags = STREAM_TOSERVER|STREAM_EOF;
3426 flags = STREAM_TOSERVER;
3435 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3438 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3441 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
3442 FAIL_IF(tx->request_method_number != HTP_M_POST);
3443 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
3453 static int HTPParserTest01a(
void)
3457 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3459 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3465 memset(&ssn, 0,
sizeof(ssn));
3467 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3471 f->
proto = IPPROTO_TCP;
3477 for (u = 0; u < httplen1; u++) {
3481 flags = STREAM_TOSERVER|STREAM_START;
3482 else if (u == (httplen1 - 1))
3483 flags = STREAM_TOSERVER|STREAM_EOF;
3485 flags = STREAM_TOSERVER;
3489 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3496 if (htp_state == NULL) {
3497 printf(
"no http state: ");
3501 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3502 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3503 if (strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0")
3504 || tx->request_method_number != HTP_M_POST ||
3505 tx->request_protocol_number != HTP_PROTOCOL_1_0)
3507 printf(
"expected header value: Victor/1.0 and got %s: and expected"
3508 " method: POST and got %s, expected protocol number HTTP/1.0"
3509 " and got: %s \n", bstr_util_strdup_to_c(h->value),
3510 bstr_util_strdup_to_c(tx->request_method),
3511 bstr_util_strdup_to_c(tx->request_protocol));
3524 static int HTPParserTest02(
void)
3528 uint8_t httpbuf1[] =
"POST";
3529 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3534 memset(&ssn, 0,
sizeof(ssn));
3536 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3540 f->
proto = IPPROTO_TCP;
3546 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3548 printf(
"toserver chunk 1 returned %" PRId32
", expected 0: ", r);
3553 if (http_state == NULL) {
3554 printf(
"no http state: ");
3558 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3560 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3564 char *method = bstr_util_strdup_to_c(tx->request_method);
3567 FAIL_IF(strcmp(method,
"POST") != 0);
3581 static int HTPParserTest03(
void)
3585 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
3586 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3592 memset(&ssn, 0,
sizeof(ssn));
3594 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3598 f->
proto = IPPROTO_TCP;
3604 for (u = 0; u < httplen1; u++) {
3607 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3608 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3609 else flags = STREAM_TOSERVER;
3613 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
3619 if (htp_state == NULL) {
3620 printf(
"no http state: ");
3624 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3626 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3627 if (tx->request_method_number != HTP_M_UNKNOWN ||
3628 h != NULL || tx->request_protocol_number != HTP_PROTOCOL_1_0)
3630 printf(
"expected method M_UNKNOWN and got %s: , expected protocol "
3631 "HTTP/1.0 and got %s \n", bstr_util_strdup_to_c(tx->request_method),
3632 bstr_util_strdup_to_c(tx->request_protocol));
3646 static int HTPParserTest04(
void)
3651 uint8_t httpbuf1[] =
"World!\r\n";
3652 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3657 memset(&ssn, 0,
sizeof(ssn));
3659 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3663 f->
proto = IPPROTO_TCP;
3669 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3675 if (htp_state == NULL) {
3676 printf(
"no http state: ");
3680 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3681 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3682 if (tx->request_method_number != HTP_M_UNKNOWN ||
3683 h != NULL || tx->request_protocol_number != HTP_PROTOCOL_0_9)
3685 printf(
"expected method M_UNKNOWN and got %s: , expected protocol "
3686 "NULL and got %s \n", bstr_util_strdup_to_c(tx->request_method),
3687 bstr_util_strdup_to_c(tx->request_protocol));
3701 static int HTPParserTest05(
void)
3703 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3704 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3705 uint8_t httpbuf2[] =
"Post D";
3706 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3707 uint8_t httpbuf3[] =
"ata is c0oL!";
3708 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3710 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3711 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3712 uint8_t httpbuf5[] =
"post R";
3713 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3714 uint8_t httpbuf6[] =
"esults are tha bomb!";
3715 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3718 memset(&ssn, 0,
sizeof(ssn));
3726 f->
proto = IPPROTO_TCP;
3756 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3758 FAIL_IF_NOT(tx->request_method_number == HTP_M_POST);
3759 FAIL_IF_NOT(tx->request_protocol_number == HTP_PROTOCOL_1_0);
3761 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3774 static int HTPParserTest06(
void)
3776 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3777 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3778 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3779 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3780 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3782 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3783 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3784 "FrontPage/5.0.2.2510\r\n"
3785 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3787 "Content-Type: text/html\r\n\r\n"
3789 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3790 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3791 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3792 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3793 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3794 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3795 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3796 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3797 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3798 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3799 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3800 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3801 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3802 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3803 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3804 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3805 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3806 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3807 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3808 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3809 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3810 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3811 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3812 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3813 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3814 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3815 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3816 "aHA=\r\n0\r\n\r\n";
3817 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3823 memset(&ssn, 0,
sizeof(ssn));
3828 f->
proto = IPPROTO_TCP;
3843 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3846 FAIL_IF(tx->request_method_number != HTP_M_GET);
3847 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
3849 FAIL_IF(tx->response_status_number != 200);
3850 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
3852 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3863 static int HTPParserTest07(
void)
3867 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| 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 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3911 size_t reflen =
sizeof(ref) - 1;
3913 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3919 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
3928 printf(
"normalized uri \"");
3950 static int HTPParserTest08(
void)
3954 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3955 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3977 memset(&ssn, 0,
sizeof(ssn));
3979 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3983 f->
proto = IPPROTO_TCP;
3989 flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
3993 printf(
"toserver chunk returned %" PRId32
", expected"
4000 if (htp_state == NULL) {
4001 printf(
"no http state: ");
4006 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4031 static int HTPParserTest09(
void)
4035 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
4036 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4046 personality: Apache_2_2\n\
4059 memset(&ssn, 0,
sizeof(ssn));
4061 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4065 f->
proto = IPPROTO_TCP;
4071 flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
4075 printf(
"toserver chunk returned %" PRId32
", expected"
4081 if (htp_state == NULL) {
4082 printf(
"no http state: ");
4086 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4111 static int HTPParserTest10(
void)
4115 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
4116 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4122 memset(&ssn, 0,
sizeof(ssn));
4124 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4128 f->
proto = IPPROTO_TCP;
4134 for (u = 0; u < httplen1; u++) {
4138 flags = STREAM_TOSERVER|STREAM_START;
4139 else if (u == (httplen1 - 1))
4140 flags = STREAM_TOSERVER|STREAM_EOF;
4142 flags = STREAM_TOSERVER;
4146 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4153 if (htp_state == NULL) {
4154 printf(
"no http state: ");
4158 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4159 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
4164 char *name = bstr_util_strdup_to_c(h->name);
4169 if (strcmp(name,
"Host") != 0) {
4170 printf(
"header name not \"Host\", instead \"%s\": ", name);
4176 char *value = bstr_util_strdup_to_c(h->value);
4177 if (value == NULL) {
4181 if (strcmp(value,
"www.google.com") != 0) {
4182 printf(
"header value not \"www.google.com\", instead \"%s\": ", value);
4199 static int HTPParserTest11(
void)
4203 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
4204 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4210 memset(&ssn, 0,
sizeof(ssn));
4212 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4216 f->
proto = IPPROTO_TCP;
4222 for (u = 0; u < httplen1; u++) {
4226 flags = STREAM_TOSERVER|STREAM_START;
4227 else if (u == (httplen1 - 1))
4228 flags = STREAM_TOSERVER|STREAM_EOF;
4230 flags = STREAM_TOSERVER;
4234 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4241 if (htp_state == NULL) {
4242 printf(
"no http state: ");
4246 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4252 printf(
"normalized uri len should be 2, is %"PRIuMAX,
4262 printf(
"normalized uri \"");
4280 static int HTPParserTest12(
void)
4284 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
4285 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4291 memset(&ssn, 0,
sizeof(ssn));
4293 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4297 f->
proto = IPPROTO_TCP;
4303 for (u = 0; u < httplen1; u++) {
4307 flags = STREAM_TOSERVER|STREAM_START;
4308 else if (u == (httplen1 - 1))
4309 flags = STREAM_TOSERVER|STREAM_EOF;
4311 flags = STREAM_TOSERVER;
4315 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4322 if (htp_state == NULL) {
4323 printf(
"no http state: ");
4327 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4333 printf(
"normalized uri len should be 5, is %"PRIuMAX,
4346 printf(
"normalized uri \"");
4364 static int HTPParserTest13(
void)
4368 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
4369 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4375 memset(&ssn, 0,
sizeof(ssn));
4377 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
4381 f->
proto = IPPROTO_TCP;
4387 for (u = 0; u < httplen1; u++) {
4391 flags = STREAM_TOSERVER|STREAM_START;
4392 else if (u == (httplen1 - 1))
4393 flags = STREAM_TOSERVER|STREAM_EOF;
4395 flags = STREAM_TOSERVER;
4399 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4406 if (htp_state == NULL) {
4407 printf(
"no http state: ");
4411 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4412 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
4417 char *name = bstr_util_strdup_to_c(h->name);
4422 if (strcmp(name,
"Host") != 0) {
4423 printf(
"header name not \"Host\", instead \"%s\": ", name);
4429 char *value = bstr_util_strdup_to_c(h->value);
4430 if (value == NULL) {
4434 if (strcmp(value,
"www.google.com\rName: Value") != 0) {
4435 printf(
"header value not \"www.google.com\", instead \"");
4453 static int HTPParserConfigTest01(
void)
4467 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4468 personality: Tomcat_6_0\n\
4473 - 192.168.10.0/24\n\
4474 personality: IIS_7_0\n\
4483 outputs =
ConfGetNode(
"libhtp.default-config.personality");
4484 if (outputs == NULL) {
4489 if (outputs == NULL) {
4497 if (strcmp(node->
name,
"0") != 0) {
4504 if (strcmp(node->
name,
"apache-tomcat") != 0) {
4512 if (node2 == NULL) {
4515 if (strcmp(node2->
val,
"Tomcat_6_0") != 0) {
4530 if (strcmp(n->
name,
"0") != 0) {
4533 if (strcmp(n->
val,
"192.168.1.0/24") != 0) {
4538 if (strcmp(n->
name,
"1") != 0) {
4541 if (strcmp(n->
val,
"127.0.0.0/8") != 0) {
4546 if (strcmp(n->
name,
"2") != 0) {
4549 if (strcmp(n->
val,
"::1") != 0) {
4560 if (outputs == NULL) {
4569 if (strcmp(node->
name,
"1") != 0) {
4576 if (strcmp(node->
name,
"iis7") != 0) {
4581 if (node2 == NULL) {
4584 if (strcmp(node2->
val,
"IIS_7_0") != 0) {
4601 if (strcmp(n->
name,
"0") != 0) {
4604 if (strcmp(n->
val,
"192.168.0.0/24") != 0) {
4609 if (strcmp(n->
name,
"1") != 0) {
4612 if (strcmp(n->
val,
"192.168.10.0/24") != 0) {
4632 static int HTPParserConfigTest02(
void)
4646 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4647 personality: Tomcat_6_0\n\
4652 - 192.168.10.0/24\n\
4653 personality: IIS_7_0\n\
4664 if (cfglist.
cfg == NULL) {
4665 printf(
"No default config created.\n");
4669 if (cfgtree == NULL) {
4670 printf(
"No config tree created.\n");
4674 htp_cfg_t *htp = cfglist.
cfg;
4677 void *user_data = NULL;
4679 addr =
"192.168.10.42";
4680 if (inet_pton(AF_INET, addr, buf) == 1) {
4682 if (user_data != NULL) {
4684 htp = htp_cfg_rec->
cfg;
4688 printf(
"Could not get config for: %s\n", addr);
4693 printf(
"Failed to parse address: %s\n", addr);
4699 if (inet_pton(AF_INET6, addr, buf) == 1) {
4701 if (user_data != NULL) {
4703 htp = htp_cfg_rec->
cfg;
4707 printf(
"Could not get config for: %s\n", addr);
4712 printf(
"Failed to parse address: %s\n", addr);
4728 static int HTPParserConfigTest03(
void)
4732 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
4734 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4751 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4752 personality: Tomcat_6_0\n\
4757 - 192.168.10.0/24\n\
4758 personality: IIS_7_0\n\
4769 const char *addr =
"192.168.10.42";
4771 memset(&ssn, 0,
sizeof(ssn));
4777 f->
proto = IPPROTO_TCP;
4780 htp_cfg_t *htp = cfglist.
cfg;
4782 void *user_data = NULL;
4784 if (user_data != NULL) {
4786 htp = htp_cfg_rec->
cfg;
4790 printf(
"Could not get config for: %s\n", addr);
4797 for (u = 0; u < httplen1; u++) {
4800 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4801 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4802 else flags = STREAM_TOSERVER;
4806 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
4814 if (htp_state == NULL) {
4815 printf(
"no http state: ");
4820 if (HTPStateGetTxCnt(htp_state) != 2) {
4821 printf(
"HTPStateGetTxCnt(htp_state) failure\n");
4825 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4828 if (tx->cfg != htp) {
4829 printf(
"wrong HTP config (%p instead of %p - default=%p): ",
4830 tx->cfg, htp, cfglist.
cfg);
4833 tx = HTPStateGetTx(htp_state, 1);
4836 if (tx->cfg != htp) {
4837 printf(
"wrong HTP config (%p instead of %p - default=%p): ",
4838 tx->cfg, htp, cfglist.
cfg);
4857 static int HTPParserConfigTest04(
void)
4868 path-control-char-handling: status_400\n\
4869 path-convert-utf8: yes\n\
4870 path-invalid-encoding-handling: remove_percent\n\
4875 personality: Tomcat_6_0\n\
4876 path-invalid-utf8-handling: none\n\
4877 path-nul-encoded-handling: status_404\n\
4878 path-nul-raw-handling: status_400\n\
4881 personality: IIS_7_0\n\
4882 path-replacement-char: o\n\
4883 path-unicode-mapping: status_400\n\
4895 if (cfg_rec->
cfg->path_control_char_handling != STATUS_400 ||
4896 cfg_rec->
cfg->path_convert_utf8 != 1 ||
4897 cfg_rec->
cfg->path_invalid_encoding_handling != URL_DECODER_REMOVE_PERCENT) {
4898 printf(
"failed 1\n");
4902 cfg_rec = cfg_rec->
next;
4903 if (cfg_rec->
cfg->bestfit_replacement_char !=
'o' ||
4904 cfg_rec->
cfg->path_unicode_mapping != STATUS_400) {
4905 printf(
"failed 2\n");
4909 cfg_rec = cfg_rec->
next;
4910 if (cfg_rec->
cfg->path_invalid_utf8_handling != NONE ||
4911 cfg_rec->
cfg->path_nul_encoded_handling != STATUS_404 ||
4912 cfg_rec->
cfg->path_nul_raw_handling != STATUS_400) {
4913 printf(
"failed 3\n");
4935 static int HTPParserDecodingTest01(
void)
4937 uint8_t httpbuf1[] =
4938 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4939 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4940 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4941 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4952 personality: Apache_2\n\
4960 const char *addr =
"4.3.2.1";
4961 memset(&ssn, 0,
sizeof(ssn));
4966 f->
proto = IPPROTO_TCP;
4971 for (uint32_t u = 0; u < httplen1; u++) {
4973 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4974 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4975 else flags = STREAM_TOSERVER;
4984 uint8_t ref1[] =
"/abc%2fdef";
4985 size_t reflen =
sizeof(ref1) - 1;
4987 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4997 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4998 reflen =
sizeof(ref2) - 1;
5000 tx = HTPStateGetTx(htp_state, 1);
5010 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
5011 reflen =
sizeof(ref3) - 1;
5012 tx = HTPStateGetTx(htp_state, 2);
5033 static int HTPParserDecodingTest01a(
void)
5035 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
5036 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
5037 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5038 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5049 personality: Apache_2\n\
5057 const char *addr =
"4.3.2.1";
5058 memset(&ssn, 0,
sizeof(ssn));
5063 f->
proto = IPPROTO_TCP;
5069 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
5075 uint8_t ref1[] =
"/abc%2fdef";
5076 size_t reflen =
sizeof(ref1) - 1;
5078 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5088 uint8_t ref2[] =
"/abc/def?ghi/jkl";
5089 reflen =
sizeof(ref2) - 1;
5091 tx = HTPStateGetTx(htp_state, 1);
5101 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
5102 reflen =
sizeof(ref3) - 1;
5103 tx = HTPStateGetTx(htp_state, 2);
5130 static int HTPParserDecodingTest02(
void)
5134 uint8_t httpbuf1[] =
5135 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
5136 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
5137 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5138 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5151 double-decode-path: no\n\
5152 double-decode-query: no\n\
5160 const char *addr =
"4.3.2.1";
5161 memset(&ssn, 0,
sizeof(ssn));
5167 f->
proto = IPPROTO_TCP;
5173 for (u = 0; u < httplen1; u++) {
5176 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5177 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5178 else flags = STREAM_TOSERVER;
5182 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5189 if (htp_state == NULL) {
5190 printf(
"no http state: ");
5194 uint8_t ref1[] =
"/abc/def";
5195 size_t reflen =
sizeof(ref1) - 1;
5197 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5203 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5212 printf(
"normalized uri \"");
5221 uint8_t ref2[] =
"/abc/def?ghi/jkl";
5222 reflen =
sizeof(ref2) - 1;
5224 tx = HTPStateGetTx(htp_state, 1);
5230 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5239 printf(
"normalized uri \"");
5248 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
5249 reflen =
sizeof(ref3) - 1;
5250 tx = HTPStateGetTx(htp_state, 2);
5256 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX
" (3): ",
5265 printf(
"normalized uri \"");
5294 static int HTPParserDecodingTest03(
void)
5298 uint8_t httpbuf1[] =
5299 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
5300 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5301 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5314 double-decode-path: yes\n\
5315 double-decode-query: yes\n\
5323 const char *addr =
"4.3.2.1";
5324 memset(&ssn, 0,
sizeof(ssn));
5330 f->
proto = IPPROTO_TCP;
5336 for (u = 0; u < httplen1; u++) {
5339 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5340 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5341 else flags = STREAM_TOSERVER;
5345 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5352 if (htp_state == NULL) {
5353 printf(
"no http state: ");
5357 uint8_t ref1[] =
"/abc/def";
5358 size_t reflen =
sizeof(ref1) - 1;
5360 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5366 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5375 printf(
"normalized uri \"");
5384 uint8_t ref2[] =
"/abc/def?ghi/jkl";
5385 reflen =
sizeof(ref2) - 1;
5387 tx = HTPStateGetTx(htp_state, 1);
5393 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5402 printf(
"normalized uri \"");
5428 static int HTPParserDecodingTest04(
void)
5432 uint8_t httpbuf1[] =
5433 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5434 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5447 double-decode-path: yes\n\
5448 double-decode-query: yes\n\
5456 const char *addr =
"4.3.2.1";
5457 memset(&ssn, 0,
sizeof(ssn));
5463 f->
proto = IPPROTO_TCP;
5469 for (u = 0; u < httplen1; u++) {
5472 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5473 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5474 else flags = STREAM_TOSERVER;
5478 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5485 if (htp_state == NULL) {
5486 printf(
"no http state: ");
5490 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
5491 size_t reflen =
sizeof(ref1) - 1;
5493 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5499 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5508 printf(
"normalized uri \"");
5534 static int HTPParserDecodingTest05(
void)
5538 uint8_t httpbuf1[] =
5539 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5540 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5553 double-decode-path: yes\n\
5554 double-decode-query: yes\n\
5562 const char *addr =
"4.3.2.1";
5563 memset(&ssn, 0,
sizeof(ssn));
5569 f->
proto = IPPROTO_TCP;
5575 for (u = 0; u < httplen1; u++) {
5578 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5579 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5580 else flags = STREAM_TOSERVER;
5584 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5591 if (htp_state == NULL) {
5592 printf(
"no http state: ");
5596 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
5597 size_t reflen =
sizeof(ref1) - 1;
5599 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5605 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5614 printf(
"normalized uri \"");
5640 static int HTPParserDecodingTest06(
void)
5644 uint8_t httpbuf1[] =
5645 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5646 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5659 double-decode-path: yes\n\
5660 double-decode-query: yes\n\
5668 const char *addr =
"4.3.2.1";
5669 memset(&ssn, 0,
sizeof(ssn));
5675 f->
proto = IPPROTO_TCP;
5681 for (u = 0; u < httplen1; u++) {
5684 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5685 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5686 else flags = STREAM_TOSERVER;
5690 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5697 if (htp_state == NULL) {
5698 printf(
"no http state: ");
5702 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
5703 size_t reflen =
sizeof(ref1) - 1;
5705 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5711 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5720 printf(
"normalized uri \"");
5746 static int HTPParserDecodingTest07(
void)
5750 uint8_t httpbuf1[] =
5751 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
5752 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5765 double-decode-path: yes\n\
5766 double-decode-query: yes\n\
5767 query-plusspace-decode: yes\n\
5775 const char *addr =
"4.3.2.1";
5776 memset(&ssn, 0,
sizeof(ssn));
5782 f->
proto = IPPROTO_TCP;
5788 for (u = 0; u < httplen1; u++) {
5791 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5792 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5793 else flags = STREAM_TOSERVER;
5797 printf(
"toserver chunk %" PRIu32
" returned %" PRId32
", expected"
5804 if (htp_state == NULL) {
5805 printf(
"no http state: ");
5809 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
5810 size_t reflen =
sizeof(ref1) - 1;
5812 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5818 printf(
"normalized uri len should be %"PRIuMAX
", is %"PRIuMAX,
5827 printf(
"normalized uri \"");