79 static struct HTPConfigTree {
95 #define HTP_MAX_MESSAGES 512
101 static uint64_t htp_state_memuse = 0;
102 static uint64_t htp_state_memcnt = 0;
112 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_REQUEST",
114 {
"INVALID_TRANSFER_ENCODING_VALUE_IN_RESPONSE",
116 {
"INVALID_CONTENT_LENGTH_FIELD_IN_REQUEST",
118 {
"INVALID_CONTENT_LENGTH_FIELD_IN_RESPONSE",
120 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_REQUEST",
122 {
"DUPLICATE_CONTENT_LENGTH_FIELD_IN_RESPONSE",
125 {
"UNABLE_TO_MATCH_RESPONSE_TO_REQUEST",
140 {
"REQUEST_SERVER_PORT_TCP_PORT_MISMATCH",
154 {
"RESPONSE_ABNORMAL_TRANSFER_ENCODING",
201 static int HTTPGetFrameIdByName(
const char *frame_name)
210 static const char *HTTPGetFrameNameById(
const uint8_t frame_id)
216 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id);
217 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction);
218 static uint64_t HTPStateGetTxCnt(
void *alstate);
220 static void HTPParserRegisterTests(
void);
223 static inline uint64_t HtpGetActiveRequestTxID(
HtpState *s)
225 uint64_t
id = HTPStateGetTxCnt(s);
230 static inline uint64_t HtpGetActiveResponseTxID(
HtpState *s)
243 static const char *HTPLookupPersonalityString(
int p)
245 #define CASE_HTP_PERSONALITY_STRING(p) \
246 case HTP_SERVER_ ## 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 = s->
tx_freed; 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;
509 static void AppLayerHtpSetStreamDepthFlag(
void *tx,
const uint8_t
flags)
514 if (
flags & STREAM_TOCLIENT) {
524 SCLogDebug(
"cfg->body_limit %u stream_depth %u body->content_len_so_far %" PRIu64,
541 static uint32_t AppLayerHtpComputeChunkLength(uint64_t content_len_so_far, uint32_t body_limit,
542 uint32_t stream_depth, uint8_t
flags, uint32_t data_len)
544 uint32_t chunk_len = 0;
546 (content_len_so_far < (uint64_t)body_limit) &&
547 (content_len_so_far + (uint64_t)data_len) > body_limit)
549 chunk_len = (uint32_t)(body_limit - content_len_so_far);
551 (content_len_so_far < (uint64_t)stream_depth) &&
552 (content_len_so_far + (uint64_t)data_len) > stream_depth)
554 chunk_len = (uint32_t)(stream_depth - content_len_so_far);
557 return (chunk_len == 0 ? data_len : chunk_len);
604 {
"Request line: URI contains non-compliant delimiter",
606 {
"Request line: non-compliant delimiter between Method and URI",
615 {
"Transfer-encoding has abnormal chunked value",
617 {
"Chunked transfer-encoding on HTTP/0.9 or HTTP/1.0",
620 {
"Invalid response line: invalid response status",
626 {
"Ambiguous response C-L value",
634 #define HTP_ERROR_MAX (sizeof(htp_errors) / sizeof(htp_errors[0]))
635 #define HTP_WARNING_MAX (sizeof(htp_warnings) / sizeof(htp_warnings[0]))
646 static uint8_t HTPHandleWarningGetId(
const char *
msg)
670 static uint8_t HTPHandleErrorGetId(
const char *
msg)
694 static void HTPHandleError(
HtpState *s,
const uint8_t dir)
696 if (s == NULL || s->
conn == NULL ||
697 s->
conn->messages == NULL) {
701 size_t size = htp_list_size(s->
conn->messages);
716 htp_log_t *log = htp_list_get(s->
conn->messages,
msg);
721 htp_tx_t *tx = log->tx;
727 uint8_t
id = HTPHandleErrorGetId(log->msg);
729 id = HTPHandleWarningGetId(log->msg);
735 HTPSetEvent(s, htud, dir,
id);
742 static inline void HTPErrorCheckTxRequestFlags(
HtpState *s, htp_tx_t *tx)
745 BUG_ON(s == NULL || tx == NULL);
747 if (tx->flags & ( HTP_REQUEST_INVALID_T_E|HTP_REQUEST_INVALID_C_L|
748 HTP_HOST_MISSING|HTP_HOST_AMBIGUOUS|HTP_HOSTU_INVALID|
755 if (tx->flags & HTP_REQUEST_INVALID_T_E)
756 HTPSetEvent(s, htud, STREAM_TOSERVER,
758 if (tx->flags & HTP_REQUEST_INVALID_C_L)
759 HTPSetEvent(s, htud, STREAM_TOSERVER,
761 if (tx->flags & HTP_HOST_MISSING)
762 HTPSetEvent(s, htud, STREAM_TOSERVER,
764 if (tx->flags & HTP_HOST_AMBIGUOUS)
765 HTPSetEvent(s, htud, STREAM_TOSERVER,
767 if (tx->flags & HTP_HOSTU_INVALID)
768 HTPSetEvent(s, htud, STREAM_TOSERVER,
770 if (tx->flags & HTP_HOSTH_INVALID)
771 HTPSetEvent(s, htud, STREAM_TOSERVER,
774 if (tx->request_auth_type == HTP_AUTH_UNRECOGNIZED) {
778 HTPSetEvent(s, htud, STREAM_TOSERVER,
781 if (tx->is_protocol_0_9 && tx->request_method_number == HTP_M_UNKNOWN &&
782 (tx->request_protocol_number == HTP_PROTOCOL_INVALID ||
783 tx->request_protocol_number == HTP_PROTOCOL_UNKNOWN)) {
787 HTPSetEvent(s, htud, STREAM_TOSERVER,
798 htp_cfg_t *htp = cfglist.
cfg;
799 void *user_data = NULL;
815 if (user_data != NULL) {
816 htp_cfg_rec = user_data;
817 htp = htp_cfg_rec->
cfg;
820 SCLogDebug(
"Using default HTP config: %p", htp);
824 #ifdef DEBUG_VALIDATION
831 hstate->
connp = htp_connp_create(htp);
832 if (hstate->
connp == NULL) {
836 hstate->
conn = htp_connp_get_connection(hstate->
connp);
838 htp_connp_set_user_data(hstate->
connp, (
void *)hstate);
839 hstate->
cfg = htp_cfg_rec;
844 htp_connp_open(hstate->
connp, NULL, f->
sp, NULL, f->
dp, &
tv);
866 StreamSlice stream_slice,
void *local_data)
876 if (NULL == hstate->
conn) {
877 if (Setup(f, hstate) != 0) {
882 hstate->
slice = &stream_slice;
884 const uint8_t *input = StreamSliceGetData(&stream_slice);
885 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
890 const int r = htp_connp_req_data(hstate->
connp, &
ts, input, input_len);
892 case HTP_STREAM_ERROR:
898 HTPHandleError(hstate, STREAM_TOSERVER);
905 htp_connp_req_close(hstate->
connp, &
ts);
907 SCLogDebug(
"stream eof encountered, closing htp handle for ts");
911 hstate->
slice = NULL;
933 StreamSlice stream_slice,
void *local_data)
939 const uint8_t *input = StreamSliceGetData(&stream_slice);
940 uint32_t input_len = StreamSliceGetDataLen(&stream_slice);
946 if (NULL == hstate->
conn) {
947 if (Setup(f, hstate) != 0) {
952 hstate->
slice = &stream_slice;
956 uint32_t consumed = 0;
958 const int r = htp_connp_res_data(hstate->
connp, &
ts, input, input_len);
960 case HTP_STREAM_ERROR:
963 case HTP_STREAM_TUNNEL:
964 tx = htp_connp_get_out_tx(hstate->
connp);
965 if (tx != NULL && tx->response_status_number == 101) {
967 (htp_header_t *)htp_table_get_c(tx->response_headers,
"Upgrade");
972 if (tx->request_port_number != -1) {
973 dp = (uint16_t)tx->request_port_number;
975 consumed = (uint32_t)htp_connp_res_data_consumed(hstate->
connp);
976 if (bstr_cmp_c(h->value,
"h2c") == 0) {
981 hstate->
slice = NULL;
983 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
988 if (consumed > 0 && consumed < input_len) {
992 }
else if (bstr_cmp_c_nocase(h->value,
"WebSocket") == 0) {
997 hstate->
slice = NULL;
999 HTPSetEvent(hstate, NULL, STREAM_TOCLIENT,
1004 if (consumed > 0 && consumed < input_len) {
1014 HTPHandleError(hstate, STREAM_TOCLIENT);
1021 htp_connp_close(hstate->
connp, &
ts);
1026 hstate->
slice = NULL;
1037 static int HTTPParseContentDispositionHeader(uint8_t *name,
size_t name_len,
1038 uint8_t *data,
size_t len, uint8_t **retptr,
size_t *retlen)
1041 printf(
"DATA START: \n");
1043 printf(
"DATA END: \n");
1048 for (x = 0; x <
len; x++) {
1049 if (!(isspace(data[x])))
1056 uint8_t *line = data+x;
1057 size_t line_len =
len-x;
1060 printf(
"LINE START: \n");
1062 printf(
"LINE END: \n");
1064 for (x = 0 ; x < line_len; x++) {
1066 if (line[x - 1] !=
'\\' && line[x] ==
'\"') {
1070 if (((line[x - 1] !=
'\\' && line[x] ==
';') || ((x + 1) == line_len)) && (quote == 0 || quote % 2 == 0)) {
1071 uint8_t *token = line +
offset;
1072 size_t token_len = x -
offset;
1074 if ((x + 1) == line_len) {
1085 printf(
"TOKEN START: \n");
1087 printf(
"TOKEN END: \n");
1089 if (token_len > name_len) {
1090 if (name == NULL || SCMemcmpLowercase(name, token, name_len) == 0) {
1091 uint8_t *value = token + name_len;
1092 size_t value_len = token_len - name_len;
1094 if (value[0] ==
'\"') {
1098 if (value[value_len-1] ==
'\"') {
1102 printf(
"VALUE START: \n");
1104 printf(
"VALUE END: \n");
1107 *retlen = value_len;
1131 static int HtpRequestBodySetupMultipart(htp_tx_t *tx,
HtpTxUserData *htud)
1133 htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->request_headers,
1135 if (h != NULL && bstr_len(h->value) > 0) {
1136 htud->
mime_state = SCMimeStateInit(bstr_ptr(h->value), (uint32_t)bstr_len(h->value));
1153 const uint8_t **chunks_buffer, uint32_t *chunks_buffer_len)
1156 chunks_buffer, chunks_buffer_len,
1160 static void FlagDetectStateNewFile(
HtpTxUserData *tx,
int dir)
1163 if (tx && tx->
tx_data.de_state) {
1164 if (dir == STREAM_TOSERVER) {
1165 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1167 }
else if (dir == STREAM_TOCLIENT) {
1168 SCLogDebug(
"DETECT_ENGINE_STATE_FLAG_FILE_NEW set");
1175 const uint8_t *chunks_buffer, uint32_t chunks_buffer_len,
bool eof)
1178 printf(
"CHUNK START: \n");
1180 printf(
"CHUNK END: \n");
1186 STREAM_TOSERVER) >= HTP_REQUEST_COMPLETE);
1188 const uint8_t *cur_buf = chunks_buffer;
1189 uint32_t cur_buf_len = chunks_buffer_len;
1205 const uint8_t *filename = NULL;
1206 uint16_t filename_len = 0;
1209 while (cur_buf_len > 0) {
1210 MimeParserResult r =
1211 SCMimeParse(htud->
mime_state, cur_buf, cur_buf_len, &consumed, &warnings);
1215 if (warnings & MIME_EVENT_FLAG_INVALID_HEADER) {
1219 if (warnings & MIME_EVENT_FLAG_NO_FILEDATA) {
1230 SCMimeStateGetFilename(htud->
mime_state, &filename, &filename_len);
1231 if (filename_len > 0) {
1235 hstate, htud, filename, filename_len, NULL, 0, STREAM_TOSERVER);
1238 }
else if (result == -2) {
1241 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1249 }
else if (result == -2) {
1257 uint32_t lastsize = consumed;
1258 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\n') {
1260 if (lastsize > 0 && cur_buf[lastsize - 1] ==
'\r') {
1264 HTPFileClose(htud, cur_buf, lastsize, 0, STREAM_TOSERVER);
1269 cur_buf += consumed;
1270 cur_buf_len -= consumed;
1282 htp_tx_t *tx, uint8_t *data, uint32_t data_len)
1289 uint8_t *filename = NULL;
1290 size_t filename_len = 0;
1293 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1294 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1295 filename_len = bstr_len(tx->parsed_uri->path);
1298 if (filename != NULL) {
1304 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1308 }
else if (result == -2) {
1311 FlagDetectStateNewFile(htud, STREAM_TOSERVER);
1325 }
else if (result == -2) {
1338 htp_tx_t *tx, uint8_t *data, uint32_t data_len)
1351 uint8_t *filename = NULL;
1352 size_t filename_len = 0;
1355 htp_header_t *h = (htp_header_t *)htp_table_get_c(tx->response_headers,
1356 "Content-Disposition");
1357 if (h != NULL && bstr_len(h->value) > 0) {
1359 (void)HTTPParseContentDispositionHeader((uint8_t *)
"filename=", 9,
1360 (uint8_t *) bstr_ptr(h->value), bstr_len(h->value), &filename, &filename_len);
1364 if (filename == NULL) {
1366 if (tx->parsed_uri != NULL && tx->parsed_uri->path != NULL) {
1367 filename = (uint8_t *)bstr_ptr(tx->parsed_uri->path);
1368 filename_len = bstr_len(tx->parsed_uri->path);
1372 if (filename != NULL) {
1374 htp_header_t *h_content_range = htp_table_get_c(tx->response_headers,
"content-range");
1380 if (h_content_range != NULL) {
1382 data_len, tx, h_content_range->value, htud);
1384 result =
HTPFileOpen(hstate, htud, filename, (uint16_t)filename_len, data, data_len,
1390 }
else if (result == -2) {
1393 FlagDetectStateNewFile(htud, STREAM_TOCLIENT);
1406 }
else if (result == -2) {
1424 static int HTPCallbackRequestBodyData(htp_tx_data_t *d)
1435 printf(
"HTPBODY START: \n");
1437 printf(
"HTPBODY END: \n");
1440 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1441 if (hstate == NULL) {
1445 SCLogDebug(
"New request body data available at %p -> %p -> %p, bodylen "
1446 "%"PRIu32
"", hstate, d, d->data, (uint32_t)d->len);
1449 if (tx_ud == NULL) {
1457 if (d->tx->request_method_number == HTP_M_POST) {
1459 int r = HtpRequestBodySetupMultipart(d->tx, tx_ud);
1462 }
else if (r == 0) {
1466 }
else if (d->tx->request_method_number == HTP_M_PUT) {
1489 const uint8_t *chunks_buffer = NULL;
1490 uint32_t chunks_buffer_len = 0;
1498 HtpRequestBodyReassemble(tx_ud, &chunks_buffer, &chunks_buffer_len);
1499 if (chunks_buffer == NULL) {
1503 printf(
"REASSCHUNK START: \n");
1505 printf(
"REASSCHUNK END: \n");
1508 HtpRequestBodyHandleMultipart(hstate, tx_ud, d->tx, chunks_buffer, chunks_buffer_len,
1509 (d->data == NULL && d->len == 0));
1513 HtpRequestBodyHandlePOSTorPUT(hstate, tx_ud, d->tx, (uint8_t *)d->data,
len);
1518 SCLogDebug(
"closing file that was being stored");
1525 if (hstate->
conn != NULL) {
1526 SCLogDebug(
"checking body size %"PRIu64
" against inspect limit %u (cur %"PRIu64
", last %"PRIu64
")",
1540 const uint32_t data_size = (uint32_t)(
1561 static int HTPCallbackResponseBodyData(htp_tx_data_t *d)
1571 HtpState *hstate = htp_connp_get_user_data(d->tx->connp);
1572 if (hstate == NULL) {
1576 SCLogDebug(
"New response body data available at %p -> %p -> %p, bodylen "
1577 "%"PRIu32
"", hstate, d, d->data, (uint32_t)d->len);
1580 if (tx_ud == NULL) {
1606 HtpResponseBodyHandle(hstate, tx_ud, d->tx, (uint8_t *)d->data,
len);
1609 SCLogDebug(
"closing file that was being stored");
1615 if (hstate->
conn != NULL) {
1616 SCLogDebug(
"checking body size %"PRIu64
" against inspect limit %u (cur %"PRIu64
", last %"PRIu64
")",
1629 const uint32_t data_size = (uint32_t)((uint64_t)hstate->
conn->out_data_counter -
1653 SCLogDebug(
"http_state_memcnt %"PRIu64
", http_state_memuse %"PRIu64
"",
1654 htp_state_memcnt, htp_state_memuse);
1672 htp_config_destroy(cfglist.
cfg);
1673 while (nextrec != NULL) {
1675 nextrec = nextrec->
next;
1677 htp_config_destroy(htprec->
cfg);
1685 static int HTPCallbackRequestHasTrailer(htp_tx_t *tx)
1694 static int HTPCallbackResponseHasTrailer(htp_tx_t *tx)
1707 static int HTPCallbackRequestStart(htp_tx_t *tx)
1709 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1710 if (hstate == NULL) {
1714 uint64_t consumed = hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1715 SCLogDebug(
"HTTP request start: data offset %" PRIu64
", in_data_counter %" PRIu64, consumed,
1716 (uint64_t)hstate->
conn->in_data_counter);
1733 if (tx_ud == NULL) {
1738 tx_ud->
tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT;
1739 htp_tx_set_user_data(tx, tx_ud);
1748 static int HTPCallbackResponseStart(htp_tx_t *tx)
1750 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1751 if (hstate == NULL) {
1755 uint64_t consumed = hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1756 SCLogDebug(
"HTTP response start: data offset %" PRIu64
", out_data_counter %" PRIu64, consumed,
1757 (uint64_t)hstate->
conn->out_data_counter);
1772 if (tx_ud == NULL) {
1779 htp_tx_set_user_data(tx, tx_ud);
1790 static int HTPCallbackRequestComplete(htp_tx_t *tx)
1798 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1799 if (hstate == NULL) {
1803 const uint64_t abs_right_edge =
1804 hstate->
slice->offset + htp_connp_req_data_consumed(hstate->
connp);
1812 SCLogDebug(
"HTTP request complete: data offset %" PRIu64
", request_size %" PRIu64,
1814 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1816 frame->
len = (int64_t)request_size;
1822 SCLogDebug(
"transaction_cnt %"PRIu64
", list_size %"PRIu64,
1827 HTPErrorCheckTxRequestFlags(hstate, tx);
1832 SCLogDebug(
"closing file that was being stored");
1835 if (abs_right_edge < (uint64_t)UINT32_MAX) {
1837 hstate->
f->
protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge);
1855 static int HTPCallbackResponseComplete(htp_tx_t *tx)
1859 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1860 if (hstate == NULL) {
1867 const uint64_t abs_right_edge =
1868 hstate->
slice->offset + htp_connp_res_data_consumed(hstate->
connp);
1875 SCLogDebug(
"HTTP response complete: data offset %" PRIu64
", response_size %" PRIu64,
1877 SCLogDebug(
"frame %p/%" PRIi64
" setting len to %" PRIu64, frame, frame->
id,
1879 frame->
len = (int64_t)response_size;
1887 SCLogDebug(
"closing file that was being stored");
1898 if (tx->request_method_number == HTP_M_CONNECT) {
1901 if ((tx->response_status_number >= 200) &&
1902 (tx->response_status_number < 300) &&
1905 if (tx->request_port_number != -1) {
1906 dp = (uint16_t)tx->request_port_number;
1913 tx->request_progress = HTP_REQUEST_COMPLETE;
1914 tx->response_progress = HTP_RESPONSE_COMPLETE;
1922 static int HTPCallbackRequestLine(htp_tx_t *tx)
1925 bstr *request_uri_normalized;
1926 HtpState *hstate = htp_connp_get_user_data(tx->connp);
1930 if (request_uri_normalized == NULL)
1933 tx_ud = htp_tx_get_user_data(tx);
1935 bstr_free(request_uri_normalized);
1943 HTPErrorCheckTxRequestFlags(hstate, tx);
1948 static int HTPCallbackDoubleDecodeUriPart(htp_tx_t *tx, bstr *part)
1954 size_t prevlen = bstr_len(part);
1955 htp_status_t res = htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, part, &
flags);
1957 if (res == HTP_OK && prevlen > bstr_len(part)) {
1961 HtpState *s = htp_connp_get_user_data(tx->connp);
1964 HTPSetEvent(s, htud, STREAM_TOSERVER,
1971 static int HTPCallbackDoubleDecodeQuery(htp_tx_t *tx)
1973 if (tx->parsed_uri == NULL)
1976 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->query);
1979 static int HTPCallbackDoubleDecodePath(htp_tx_t *tx)
1981 if (tx->parsed_uri == NULL)
1984 return HTPCallbackDoubleDecodeUriPart(tx, tx->parsed_uri->path);
1987 static int HTPCallbackRequestHeaderData(htp_tx_data_t *tx_data)
1990 if (tx_data->len == 0 || tx_data->tx == NULL)
1994 if (tx_ud == NULL) {
2006 tx_data->data, tx_data->len);
2009 if (tx_data->tx && tx_data->tx->flags) {
2010 HtpState *hstate = htp_connp_get_user_data(tx_data->tx->connp);
2011 HTPErrorCheckTxRequestFlags(hstate, tx_data->tx);
2016 static int HTPCallbackResponseHeaderData(htp_tx_data_t *tx_data)
2019 if (tx_data->len == 0 || tx_data->tx == NULL)
2023 if (tx_ud == NULL) {
2035 tx_data->data, tx_data->len);
2044 static void HTPConfigSetDefaultsPhase1(
HTPCfgRec *cfg_prec)
2061 htp_config_register_request_header_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2062 htp_config_register_request_trailer_data(cfg_prec->
cfg, HTPCallbackRequestHeaderData);
2063 htp_config_register_response_header_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2064 htp_config_register_response_trailer_data(cfg_prec->
cfg, HTPCallbackResponseHeaderData);
2066 htp_config_register_request_trailer(cfg_prec->
cfg, HTPCallbackRequestHasTrailer);
2067 htp_config_register_response_trailer(cfg_prec->
cfg, HTPCallbackResponseHasTrailer);
2069 htp_config_register_request_body_data(cfg_prec->
cfg, HTPCallbackRequestBodyData);
2070 htp_config_register_response_body_data(cfg_prec->
cfg, HTPCallbackResponseBodyData);
2072 htp_config_register_request_start(cfg_prec->
cfg, HTPCallbackRequestStart);
2073 htp_config_register_request_complete(cfg_prec->
cfg, HTPCallbackRequestComplete);
2075 htp_config_register_response_start(cfg_prec->
cfg, HTPCallbackResponseStart);
2076 htp_config_register_response_complete(cfg_prec->
cfg, HTPCallbackResponseComplete);
2078 htp_config_set_parse_request_cookies(cfg_prec->
cfg, 0);
2079 #ifdef HAVE_HTP_CONFIG_SET_ALLOW_SPACE_URI
2080 htp_config_set_allow_space_uri(cfg_prec->
cfg, 1);
2084 htp_config_set_plusspace_decode(cfg_prec->
cfg, HTP_DECODER_URLENCODED, 0);
2086 htp_config_set_request_decompression(cfg_prec->
cfg, 1);
2087 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2091 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2092 htp_config_set_lzma_memlimit(cfg_prec->
cfg,
2095 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2096 htp_config_set_compression_bomb_limit(cfg_prec->
cfg,
2099 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2102 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2103 #define HTP_CONFIG_DEFAULT_MAX_TX_LIMIT 512
2104 htp_config_set_max_tx(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_MAX_TX_LIMIT);
2106 #ifdef HAVE_HTP_CONFIG_SET_HEADERS_LIMIT
2107 #define HTP_CONFIG_DEFAULT_HEADERS_LIMIT 1024
2108 htp_config_set_number_headers_limit(cfg_prec->
cfg, HTP_CONFIG_DEFAULT_HEADERS_LIMIT);
2123 static int RandomGetWrap(
void)
2129 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
2131 return r % RAND_MAX;
2140 static void HTPConfigSetDefaultsPhase2(
const char *name,
HTPCfgRec *cfg_prec)
2146 long int r = RandomGetWrap();
2148 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2150 r = RandomGetWrap();
2152 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2153 SCLogConfig(
"'%s' server has 'request-body-minimal-inspect-size' set to"
2154 " %u and 'request-body-inspect-window' set to %u after"
2158 r = RandomGetWrap();
2160 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2162 r = RandomGetWrap();
2164 ((
double)r / RAND_MAX - 0.5) * rdrange / 100);
2166 SCLogConfig(
"'%s' server has 'response-body-minimal-inspect-size' set to"
2167 " %u and 'response-body-inspect-window' set to %u after"
2172 htp_config_register_request_line(cfg_prec->
cfg, HTPCallbackRequestLine);
2175 static void HTPConfigParseParameters(
HTPCfgRec *cfg_prec,
ConfNode *s,
struct HTPConfigTree *tree)
2177 if (cfg_prec == NULL || s == NULL || tree == NULL)
2184 if (strcasecmp(
"address", p->
name) == 0) {
2190 if (strchr(pval->
val,
':') != NULL) {
2191 SCLogDebug(
"LIBHTP adding ipv6 server %s at %s: %p",
2195 SCLogWarning(
"LIBHTP failed to add ipv6 server %s, ignoring", pval->
val);
2198 SCLogDebug(
"LIBHTP adding ipv4 server %s at %s: %p",
2202 SCLogWarning(
"LIBHTP failed to add ipv4 server %s, ignoring", pval->
val);
2207 }
else if (strcasecmp(
"personality", p->
name) == 0) {
2209 int personality = HTPLookupPersonality(p->
val);
2213 if (personality >= 0) {
2216 if (htp_config_set_server_personality(cfg_prec->
cfg, personality) == HTP_ERROR){
2218 "personality \"%s\", ignoring",
2222 HTPLookupPersonalityString(personality));
2228 htp_config_set_convert_lowercase(cfg_prec->
cfg, HTP_DECODER_URL_PATH, 0);
2236 }
else if (strcasecmp(
"request-body-limit", p->
name) == 0 ||
2237 strcasecmp(
"request_body_limit", p->
name) == 0) {
2239 SCLogError(
"Error parsing request-body-limit "
2240 "from conf file - %s. Killing engine",
2245 }
else if (strcasecmp(
"response-body-limit", p->
name) == 0) {
2247 SCLogError(
"Error parsing response-body-limit "
2248 "from conf file - %s. Killing engine",
2253 }
else if (strcasecmp(
"request-body-minimal-inspect-size", p->
name) == 0) {
2255 SCLogError(
"Error parsing request-body-minimal-inspect-size "
2256 "from conf file - %s. Killing engine",
2261 }
else if (strcasecmp(
"request-body-inspect-window", p->
name) == 0) {
2263 SCLogError(
"Error parsing request-body-inspect-window "
2264 "from conf file - %s. Killing engine",
2269 }
else if (strcasecmp(
"double-decode-query", p->
name) == 0) {
2271 htp_config_register_request_line(cfg_prec->
cfg,
2272 HTPCallbackDoubleDecodeQuery);
2275 }
else if (strcasecmp(
"double-decode-path", p->
name) == 0) {
2277 htp_config_register_request_line(cfg_prec->
cfg,
2278 HTPCallbackDoubleDecodePath);
2281 }
else if (strcasecmp(
"response-body-minimal-inspect-size", p->
name) == 0) {
2283 SCLogError(
"Error parsing response-body-minimal-inspect-size "
2284 "from conf file - %s. Killing engine",
2289 }
else if (strcasecmp(
"response-body-inspect-window", p->
name) == 0) {
2291 SCLogError(
"Error parsing response-body-inspect-window "
2292 "from conf file - %s. Killing engine",
2297 }
else if (strcasecmp(
"response-body-decompress-layer-limit", p->
name) == 0) {
2300 SCLogError(
"Error parsing response-body-inspect-window "
2301 "from conf file - %s. Killing engine",
2305 #ifdef HAVE_HTP_CONFIG_SET_RESPONSE_DECOMPRESSION_LAYER_LIMIT
2306 htp_config_set_response_decompression_layer_limit(cfg_prec->
cfg, value);
2308 SCLogWarning(
"can't set response-body-decompress-layer-limit "
2309 "to %u, libhtp version too old",
2312 }
else if (strcasecmp(
"path-convert-backslash-separators", p->
name) == 0) {
2313 htp_config_set_backslash_convert_slashes(cfg_prec->
cfg,
2314 HTP_DECODER_URL_PATH,
2316 }
else if (strcasecmp(
"path-bestfit-replacement-char", p->
name) == 0) {
2317 if (strlen(p->
val) == 1) {
2318 htp_config_set_bestfit_replacement_byte(cfg_prec->
cfg,
2319 HTP_DECODER_URL_PATH,
2323 "for libhtp param path-bestfit-replacement-char");
2325 }
else if (strcasecmp(
"path-convert-lowercase", p->
name) == 0) {
2326 htp_config_set_convert_lowercase(cfg_prec->
cfg,
2327 HTP_DECODER_URL_PATH,
2329 }
else if (strcasecmp(
"path-nul-encoded-terminates", p->
name) == 0) {
2330 htp_config_set_nul_encoded_terminates(cfg_prec->
cfg,
2331 HTP_DECODER_URL_PATH,
2333 }
else if (strcasecmp(
"path-nul-raw-terminates", p->
name) == 0) {
2334 htp_config_set_nul_raw_terminates(cfg_prec->
cfg,
2335 HTP_DECODER_URL_PATH,
2337 }
else if (strcasecmp(
"path-separators-compress", p->
name) == 0) {
2338 htp_config_set_path_separators_compress(cfg_prec->
cfg,
2339 HTP_DECODER_URL_PATH,
2341 }
else if (strcasecmp(
"path-separators-decode", p->
name) == 0) {
2342 htp_config_set_path_separators_decode(cfg_prec->
cfg,
2343 HTP_DECODER_URL_PATH,
2345 }
else if (strcasecmp(
"path-u-encoding-decode", p->
name) == 0) {
2346 htp_config_set_u_encoding_decode(cfg_prec->
cfg,
2347 HTP_DECODER_URL_PATH,
2349 }
else if (strcasecmp(
"path-url-encoding-invalid-handling", p->
name) == 0) {
2350 enum htp_url_encoding_handling_t handling;
2351 if (strcasecmp(p->
val,
"preserve_percent") == 0) {
2352 handling = HTP_URL_DECODE_PRESERVE_PERCENT;
2353 }
else if (strcasecmp(p->
val,
"remove_percent") == 0) {
2354 handling = HTP_URL_DECODE_REMOVE_PERCENT;
2355 }
else if (strcasecmp(p->
val,
"decode_invalid") == 0) {
2356 handling = HTP_URL_DECODE_PROCESS_INVALID;
2359 "for libhtp param path-url-encoding-invalid-handling");
2362 htp_config_set_url_encoding_invalid_handling(cfg_prec->
cfg,
2363 HTP_DECODER_URL_PATH,
2365 }
else if (strcasecmp(
"path-utf8-convert-bestfit", p->
name) == 0) {
2366 htp_config_set_utf8_convert_bestfit(cfg_prec->
cfg,
2367 HTP_DECODER_URL_PATH,
2369 }
else if (strcasecmp(
"uri-include-all", p->
name) == 0) {
2373 }
else if (strcasecmp(
"query-plusspace-decode", p->
name) == 0) {
2374 htp_config_set_plusspace_decode(cfg_prec->
cfg,
2375 HTP_DECODER_URLENCODED,
2377 }
else if (strcasecmp(
"meta-field-limit", p->
name) == 0) {
2381 "from conf file - %s. Killing engine",
2387 "from conf file cannot be 0. Killing engine");
2390 htp_config_set_field_limits(cfg_prec->
cfg,
2393 #ifdef HAVE_HTP_CONFIG_SET_LZMA_MEMLIMIT
2394 }
else if (strcasecmp(
"lzma-memlimit", p->
name) == 0) {
2397 FatalError(
"failed to parse 'lzma-memlimit' "
2398 "from conf file - %s.",
2403 "from conf file cannot be 0.");
2406 SCLogConfig(
"Setting HTTP LZMA memory limit to %"PRIu32
" bytes", limit);
2407 htp_config_set_lzma_memlimit(cfg_prec->
cfg, (
size_t)limit);
2409 #ifdef HAVE_HTP_CONFIG_SET_LZMA_LAYERS
2410 }
else if (strcasecmp(
"lzma-enabled", p->
name) == 0) {
2412 htp_config_set_lzma_layers(cfg_prec->
cfg, 1);
2417 "from conf file - %s.",
2420 SCLogConfig(
"Setting HTTP LZMA decompression layers to %" PRIu32
"", (
int)limit);
2421 htp_config_set_lzma_layers(cfg_prec->
cfg, limit);
2424 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_BOMB_LIMIT
2425 }
else if (strcasecmp(
"compression-bomb-limit", p->
name) == 0) {
2428 FatalError(
"failed to parse 'compression-bomb-limit' "
2429 "from conf file - %s.",
2434 "from conf file cannot be 0.");
2437 SCLogConfig(
"Setting HTTP compression bomb limit to %"PRIu32
" bytes", limit);
2438 htp_config_set_compression_bomb_limit(cfg_prec->
cfg, (
size_t)limit);
2440 #ifdef HAVE_HTP_CONFIG_SET_COMPRESSION_TIME_LIMIT
2441 }
else if (strcasecmp(
"decompression-time-limit", p->
name) == 0) {
2445 FatalError(
"failed to parse 'decompression-time-limit' "
2446 "from conf file - %s.",
2449 SCLogConfig(
"Setting HTTP decompression time limit to %" PRIu32
" usec", limit);
2450 htp_config_set_compression_time_limit(cfg_prec->
cfg, (
size_t)limit);
2452 #ifdef HAVE_HTP_CONFIG_SET_MAX_TX
2453 }
else if (strcasecmp(
"max-tx", p->
name) == 0) {
2457 "from conf file - %s.",
2461 SCLogConfig(
"Setting HTTP max-tx limit to %" PRIu32
" bytes", limit);
2462 htp_config_set_max_tx(cfg_prec->
cfg, limit);
2464 #ifdef HAVE_HTP_CONFIG_SET_HEADERS_LIMIT
2465 }
else if (strcasecmp(
"headers-limit", p->
name) == 0) {
2468 FatalError(
"failed to parse 'headers-limit' "
2469 "from conf file - %s.",
2472 SCLogConfig(
"Setting HTTP headers limit to %" PRIu32, limit);
2473 htp_config_set_number_headers_limit(cfg_prec->
cfg, limit);
2475 }
else if (strcasecmp(
"randomize-inspection-sizes", p->
name) == 0) {
2479 }
else if (strcasecmp(
"randomize-inspection-range", p->
name) == 0) {
2482 (
const char *)p->
val, 0, 100) < 0) {
2484 "-inspection-range setting from conf file - \"%s\"."
2485 " It should be a valid integer less than or equal to 100."
2491 }
else if (strcasecmp(
"http-body-inline", p->
name) == 0) {
2497 if (strcmp(
"auto", p->
val) != 0) {
2506 }
else if (strcasecmp(
"swf-decompression", p->
name) == 0) {
2510 if (strcasecmp(
"enabled", pval->
name) == 0) {
2518 }
else if (strcasecmp(
"type", pval->
name) == 0) {
2519 if (strcasecmp(
"no", pval->
val) == 0) {
2521 }
else if (strcasecmp(
"deflate", pval->
val) == 0) {
2523 }
else if (strcasecmp(
"lzma", pval->
val) == 0) {
2525 }
else if (strcasecmp(
"both", pval->
val) == 0) {
2529 "swf-decompression.type: %s - "
2534 }
else if (strcasecmp(
"compress-depth", pval->
name) == 0) {
2536 SCLogError(
"Error parsing swf-decompression.compression-depth "
2537 "from conf file - %s. Killing engine",
2541 }
else if (strcasecmp(
"decompress-depth", pval->
name) == 0) {
2543 SCLogError(
"Error parsing swf-decompression.decompression-depth "
2544 "from conf file - %s. Killing engine",
2554 "default config: %s",
2564 cfglist.
next = NULL;
2571 cfglist.
cfg = htp_config_create();
2572 if (NULL == cfglist.
cfg) {
2573 FatalError(
"Failed to create HTP default config");
2576 HTPConfigSetDefaultsPhase1(&cfglist);
2577 if (
ConfGetNode(
"app-layer.protocols.http.libhtp") == NULL) {
2578 HTPConfigParseParameters(&cfglist,
ConfGetNode(
"libhtp.default-config"), &cfgtree);
2580 HTPConfigParseParameters(
2581 &cfglist,
ConfGetNode(
"app-layer.protocols.http.libhtp.default-config"), &cfgtree);
2583 HTPConfigSetDefaultsPhase2(
"default", &cfglist);
2589 if (server_config == NULL) {
2590 server_config =
ConfGetNode(
"libhtp.server-config");
2591 if (server_config == NULL) {
2592 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2596 SCLogDebug(
"LIBHTP Configuring %p", server_config);
2615 cfglist.
next = htprec;
2618 cfglist.
next->
cfg = htp_config_create();
2619 if (NULL == cfglist.
next->
cfg) {
2620 FatalError(
"Failed to create HTP server config");
2623 HTPConfigSetDefaultsPhase1(htprec);
2624 HTPConfigParseParameters(htprec, s, &cfgtree);
2625 HTPConfigSetDefaultsPhase2(s->
name, htprec);
2635 SCLogPerf(
"htp memory %"PRIu64
" (%"PRIu64
")", htp_state_memuse, htp_state_memcnt);
2646 static AppLayerGetFileState HTPGetTxFiles(
void *txv, uint8_t direction)
2648 AppLayerGetFileState files = { .fc = NULL, .cfg = &
htp_sbcfg };
2649 htp_tx_t *tx = (htp_tx_t *)txv;
2652 if (direction & STREAM_TOCLIENT) {
2661 static int HTPStateGetAlstateProgress(
void *tx, uint8_t direction)
2663 if (direction & STREAM_TOSERVER)
2664 return ((htp_tx_t *)tx)->request_progress;
2666 return ((htp_tx_t *)tx)->response_progress;
2669 static uint64_t HTPStateGetTxCnt(
void *alstate)
2673 if (http_state != NULL && http_state->
conn != NULL) {
2674 const int64_t size = (int64_t)htp_list_size(http_state->
conn->transactions);
2678 return (uint64_t)size + http_state->
tx_freed;
2684 static void *HTPStateGetTx(
void *alstate, uint64_t tx_id)
2688 if (http_state != NULL && http_state->
conn != NULL && tx_id >= http_state->
tx_freed)
2689 return htp_list_get(http_state->
conn->transactions, tx_id - http_state->
tx_freed);
2698 if (http_state != NULL && http_state->
conn != NULL) {
2699 size_t txid = HTPStateGetTxCnt(http_state);
2701 return htp_list_get(http_state->
conn->transactions, txid - http_state->
tx_freed - 1);
2707 static int HTPStateGetEventInfo(
2708 const char *event_name, uint8_t *event_id, AppLayerEventType *event_type)
2711 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2717 static int HTPStateGetEventInfoById(
2718 uint8_t event_id,
const char **event_name, AppLayerEventType *event_type)
2721 if (*event_name == NULL) {
2723 "http's enum map table.",
2729 *event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
2736 htp_tx_t *tx = (htp_tx_t *)vtx;
2744 static AppLayerStateData *HTPGetStateData(
void *vstate)
2750 static int HTPRegisterPatternsForProtocolDetection(
void)
2752 const char *methods[] = {
"GET",
"PUT",
"POST",
"HEAD",
"TRACE",
"OPTIONS",
2753 "CONNECT",
"DELETE",
"PATCH",
"PROPFIND",
"PROPPATCH",
"MKCOL",
2754 "COPY",
"MOVE",
"LOCK",
"UNLOCK",
"CHECKOUT",
"UNCHECKOUT",
"CHECKIN",
2755 "UPDATE",
"LABEL",
"REPORT",
"MKWORKSPACE",
"MKACTIVITY",
"MERGE",
2756 "INVALID",
"VERSION-CONTROL",
"BASELINE-CONTROL", NULL};
2757 const char *spacings[] = {
"|20|",
"|09|", NULL };
2758 const char *versions[] = {
"HTTP/0.9",
"HTTP/1.0",
"HTTP/1.1", NULL };
2763 int register_result;
2764 char method_buffer[32] =
"";
2767 for (methods_pos = 0; methods[methods_pos]; methods_pos++) {
2768 for (spacings_pos = 0; spacings[spacings_pos]; spacings_pos++) {
2771 snprintf(method_buffer,
sizeof(method_buffer),
"%s%s", methods[methods_pos], spacings[spacings_pos]);
2778 method_buffer, (uint16_t)strlen(method_buffer) - 3, 0, STREAM_TOSERVER);
2779 if (register_result < 0) {
2786 for (versions_pos = 0; versions[versions_pos]; versions_pos++) {
2788 versions[versions_pos], (uint16_t)strlen(versions[versions_pos]), 0,
2790 if (register_result < 0) {
2806 const char *proto_name =
"http";
2811 if (HTPRegisterPatternsForProtocolDetection() < 0)
2814 SCLogInfo(
"Protocol detection and parser disabled for %s protocol",
2829 ALPROTO_HTTP1, HTP_REQUEST_COMPLETE, HTP_RESPONSE_COMPLETE);
2841 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER, HTPHandleRequestData);
2843 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOCLIENT, HTPHandleResponseData);
2849 IPPROTO_TCP,
ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_TOCLIENT);
2852 IPPROTO_TCP,
ALPROTO_HTTP1, HTTPGetFrameIdByName, HTTPGetFrameNameById);
2856 SCLogInfo(
"Parser disabled for %s protocol. Protocol detection still on.", proto_name);
2872 cfglist_backup = cfglist;
2877 cfglist = cfglist_backup;
2882 static int HTPParserTest01(
void)
2884 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
2886 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2889 memset(&ssn, 0,
sizeof(ssn));
2897 f->
proto = IPPROTO_TCP;
2903 for (u = 0; u < httplen1; u++) {
2907 flags = STREAM_TOSERVER|STREAM_START;
2908 else if (u == (httplen1 - 1))
2909 flags = STREAM_TOSERVER|STREAM_EOF;
2911 flags = STREAM_TOSERVER;
2920 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2923 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
2926 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
2927 FAIL_IF(tx->request_method_number != HTP_M_POST);
2928 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
2937 static int HTPParserTest01b(
void)
2939 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2941 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2944 memset(&ssn, 0,
sizeof(ssn));
2952 f->
proto = IPPROTO_TCP;
2957 uint8_t
flags =STREAM_TOSERVER|STREAM_START|STREAM_EOF;
2964 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
2967 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
2970 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
2971 FAIL_IF(tx->request_method_number != HTP_M_POST);
2972 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
2981 static int HTPParserTest01c(
void)
2983 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent:\r\n Victor/1.0\r\n\r\nPost"
2985 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
2988 memset(&ssn, 0,
sizeof(ssn));
2996 f->
proto = IPPROTO_TCP;
3002 for (u = 0; u < httplen1; u++) {
3006 flags = STREAM_TOSERVER|STREAM_START;
3007 else if (u == (httplen1 - 1))
3008 flags = STREAM_TOSERVER|STREAM_EOF;
3010 flags = STREAM_TOSERVER;
3019 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3022 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3025 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
3026 FAIL_IF(tx->request_method_number != HTP_M_POST);
3027 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
3037 static int HTPParserTest01a(
void)
3040 uint8_t httpbuf1[] =
" POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
3042 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3047 memset(&ssn, 0,
sizeof(ssn));
3049 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3052 f->
proto = IPPROTO_TCP;
3058 for (u = 0; u < httplen1; u++) {
3062 flags = STREAM_TOSERVER|STREAM_START;
3063 else if (u == (httplen1 - 1))
3064 flags = STREAM_TOSERVER|STREAM_EOF;
3066 flags = STREAM_TOSERVER;
3075 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3078 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3081 FAIL_IF(strcmp(bstr_util_strdup_to_c(h->value),
"Victor/1.0"));
3082 FAIL_IF(tx->request_method_number != HTP_M_POST);
3083 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
3092 static int HTPParserTest02(
void)
3095 uint8_t httpbuf1[] =
"POST";
3096 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3101 memset(&ssn, 0,
sizeof(ssn));
3103 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3106 f->
proto = IPPROTO_TCP;
3112 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3118 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3120 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3124 char *method = bstr_util_strdup_to_c(tx->request_method);
3127 FAIL_IF(strcmp(method,
"POST") != 0);
3138 static int HTPParserTest03(
void)
3141 uint8_t httpbuf1[] =
"HELLO / HTTP/1.0\r\n";
3142 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3147 memset(&ssn, 0,
sizeof(ssn));
3149 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3152 f->
proto = IPPROTO_TCP;
3158 for (u = 0; u < httplen1; u++) {
3161 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
3162 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
3163 else flags = STREAM_TOSERVER;
3171 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3174 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3176 FAIL_IF(tx->request_method_number != HTP_M_UNKNOWN);
3177 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_0);
3187 static int HTPParserTest04(
void)
3191 uint8_t httpbuf1[] =
"World!\r\n";
3192 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3196 memset(&ssn, 0,
sizeof(ssn));
3198 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3201 f->
proto = IPPROTO_TCP;
3207 STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
3213 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3215 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3218 FAIL_IF(tx->request_method_number != HTP_M_UNKNOWN);
3219 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_0_9);
3229 static int HTPParserTest05(
void)
3231 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\nContent-Length: 17\r\n\r\n";
3232 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3233 uint8_t httpbuf2[] =
"Post D";
3234 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3235 uint8_t httpbuf3[] =
"ata is c0oL!";
3236 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3238 uint8_t httpbuf4[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3239 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3240 uint8_t httpbuf5[] =
"post R";
3241 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3242 uint8_t httpbuf6[] =
"esults are tha bomb!";
3243 uint32_t httplen6 =
sizeof(httpbuf6) - 1;
3246 memset(&ssn, 0,
sizeof(ssn));
3254 f->
proto = IPPROTO_TCP;
3284 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3286 FAIL_IF_NOT(tx->request_method_number == HTP_M_POST);
3287 FAIL_IF_NOT(tx->request_protocol_number == HTP_PROTOCOL_1_0);
3289 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3302 static int HTPParserTest06(
void)
3304 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
3305 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
3306 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
3307 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3308 uint8_t httpbuf2[] =
"HTTP/1.1 200 OK\r\nDate: Sat, 03 Oct 2009 10:16:02 "
3310 "Server: Apache/1.3.37 (Unix) mod_ssl/2.8.28 "
3311 "OpenSSL/0.9.7a PHP/4.4.7 mod_perl/1.29 "
3312 "FrontPage/5.0.2.2510\r\n"
3313 "X-Powered-By: PHP/4.4.7\r\nTransfer-Encoding: "
3315 "Content-Type: text/html\r\n\r\n"
3317 "W2dyb3VwMV0NCnBob25lMT1wMDB3ODgyMTMxMzAyMTINCmxvZ2lu"
3318 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj1wMDB3ODgyMTMxMzAyMTIN"
3319 "CmxvZ2luMj0NCnBhc3N3b3JkMj0NCnBob25lMz0NCmxvZ2luMz0N"
3320 "CnBhc3N3b3JkMz0NCnBob25lND0NCmxvZ2luND0NCnBhc3N3b3Jk"
3321 "ND0NCnBob25lNT0NCmxvZ2luNT0NCnBhc3N3b3JkNT0NCnBob25l"
3322 "Nj0NCmxvZ2luNj0NCnBhc3N3b3JkNj0NCmNhbGxfdGltZTE9MzIN"
3323 "CmNhbGxfdGltZTI9MjMyDQpkYXlfbGltaXQ9NQ0KbW9udGhfbGlt"
3324 "aXQ9MTUNCltncm91cDJdDQpwaG9uZTE9DQpsb2dpbjE9DQpwYXNz"
3325 "d29yZDE9DQpwaG9uZTI9DQpsb2dpbjI9DQpwYXNzd29yZDI9DQpw"
3326 "aG9uZTM9DQpsb2dpbjM9DQpwYXNzd29yZDM9DQpwaG9uZTQ9DQps"
3327 "b2dpbjQ9DQpwYXNzd29yZDQ9DQpwaG9uZTU9DQpsb2dpbjU9DQpw"
3328 "YXNzd29yZDU9DQpwaG9uZTY9DQpsb2dpbjY9DQpwYXNzd29yZDY9"
3329 "DQpjYWxsX3RpbWUxPQ0KY2FsbF90aW1lMj0NCmRheV9saW1pdD0N"
3330 "Cm1vbnRoX2xpbWl0PQ0KW2dyb3VwM10NCnBob25lMT0NCmxvZ2lu"
3331 "MT0NCnBhc3N3b3JkMT0NCnBob25lMj0NCmxvZ2luMj0NCnBhc3N3"
3332 "b3JkMj0NCnBob25lMz0NCmxvZ2luMz0NCnBhc3N3b3JkMz0NCnBo"
3333 "b25lND0NCmxvZ2luND0NCnBhc3N3b3JkND0NCnBob25lNT0NCmxv"
3334 "Z2luNT0NCnBhc3N3b3JkNT0NCnBob25lNj0NCmxvZ2luNj0NCnBh"
3335 "c3N3b3JkNj0NCmNhbGxfdGltZTE9DQpjYWxsX3RpbWUyPQ0KZGF5"
3336 "X2xpbWl0PQ0KbW9udGhfbGltaXQ9DQpbZ3JvdXA0XQ0KcGhvbmUx"
3337 "PQ0KbG9naW4xPQ0KcGFzc3dvcmQxPQ0KcGhvbmUyPQ0KbG9naW4y"
3338 "PQ0KcGFzc3dvcmQyPQ0KcGhvbmUzPQ0KbG9naW4zPQ0KcGFzc3dv"
3339 "cmQzPQ0KcGhvbmU0PQ0KbG9naW40PQ0KcGFzc3dvcmQ0PQ0KcGhv"
3340 "bmU1PQ0KbG9naW41PQ0KcGFzc3dvcmQ1PQ0KcGhvbmU2PQ0KbG9n"
3341 "aW42PQ0KcGFzc3dvcmQ2PQ0KY2FsbF90aW1lMT0NCmNhbGxfdGlt"
3342 "ZTI9DQpkYXlfbGltaXQ9DQptb250aF9saW1pdD0NCltmaWxlc10N"
3343 "Cmxpbms9aHR0cDovLzIwOS4yMDUuMTk2LjE2L2xkL2dldGJvdC5w"
3344 "aHA=\r\n0\r\n\r\n";
3345 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3351 memset(&ssn, 0,
sizeof(ssn));
3356 f->
proto = IPPROTO_TCP;
3371 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
3374 FAIL_IF(tx->request_method_number != HTP_M_GET);
3375 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
3377 FAIL_IF(tx->response_status_number != 200);
3378 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
3380 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3391 static int HTPParserTest07(
void)
3394 uint8_t httpbuf1[] =
"GET /awstats.pl?/migratemigrate%20=%20| HTTP/1.0\r\n\r\n";
3395 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3400 memset(&ssn, 0,
sizeof(ssn));
3402 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3405 f->
proto = IPPROTO_TCP;
3411 for (u = 0; u < httplen1; u++) {
3415 flags = STREAM_TOSERVER|STREAM_START;
3416 else if (u == (httplen1 - 1))
3417 flags = STREAM_TOSERVER|STREAM_EOF;
3419 flags = STREAM_TOSERVER;
3428 uint8_t ref[] =
"/awstats.pl?/migratemigrate = |";
3429 size_t reflen =
sizeof(ref) - 1;
3431 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3452 static int HTPParserTest08(
void)
3455 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3456 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3477 memset(&ssn, 0,
sizeof(ssn));
3479 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3482 f->
proto = IPPROTO_TCP;
3487 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3495 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3515 static int HTPParserTest09(
void)
3518 uint8_t httpbuf1[] =
"GET /secondhouse/image/js/\%ce\%de\%ce\%fd_RentCity.js?v=2011.05.02 HTTP/1.0\r\n\r\n";
3519 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3529 personality: Apache_2_2\n\
3541 memset(&ssn, 0,
sizeof(ssn));
3543 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3546 f->
proto = IPPROTO_TCP;
3551 uint8_t
flags = STREAM_TOSERVER | STREAM_START | STREAM_EOF;
3559 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3580 static int HTPParserTest10(
void)
3584 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\r\n\r\n";
3585 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3590 memset(&ssn, 0,
sizeof(ssn));
3592 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3595 f->
proto = IPPROTO_TCP;
3601 for (u = 0; u < httplen1; u++) {
3605 flags = STREAM_TOSERVER|STREAM_START;
3606 else if (u == (httplen1 - 1))
3607 flags = STREAM_TOSERVER|STREAM_EOF;
3609 flags = STREAM_TOSERVER;
3618 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3619 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3622 char *name = bstr_util_strdup_to_c(h->name);
3624 FAIL_IF(strcmp(name,
"Host") != 0);
3626 char *value = bstr_util_strdup_to_c(h->value);
3628 FAIL_IF(strcmp(value,
"www.google.com") != 0);
3640 static int HTPParserTest11(
void)
3643 uint8_t httpbuf1[] =
"GET /%2500 HTTP/1.0\r\n\r\n";
3644 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3649 memset(&ssn, 0,
sizeof(ssn));
3651 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3654 f->
proto = IPPROTO_TCP;
3660 for (u = 0; u < httplen1; u++) {
3664 flags = STREAM_TOSERVER|STREAM_START;
3665 else if (u == (httplen1 - 1))
3666 flags = STREAM_TOSERVER|STREAM_EOF;
3668 flags = STREAM_TOSERVER;
3677 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3699 static int HTPParserTest12(
void)
3702 uint8_t httpbuf1[] =
"GET /?a=%2500 HTTP/1.0\r\n\r\n";
3703 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3708 memset(&ssn, 0,
sizeof(ssn));
3710 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3713 f->
proto = IPPROTO_TCP;
3719 for (u = 0; u < httplen1; u++) {
3723 flags = STREAM_TOSERVER|STREAM_START;
3724 else if (u == (httplen1 - 1))
3725 flags = STREAM_TOSERVER|STREAM_EOF;
3727 flags = STREAM_TOSERVER;
3736 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3760 static int HTPParserTest13(
void)
3763 uint8_t httpbuf1[] =
"GET / HTTP/1.0\r\nHost:www.google.com\rName: Value\r\n\r\n";
3764 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3769 memset(&ssn, 0,
sizeof(ssn));
3771 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
3774 f->
proto = IPPROTO_TCP;
3780 for (u = 0; u < httplen1; u++) {
3784 flags = STREAM_TOSERVER|STREAM_START;
3785 else if (u == (httplen1 - 1))
3786 flags = STREAM_TOSERVER|STREAM_EOF;
3788 flags = STREAM_TOSERVER;
3796 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
3797 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
3800 char *name = bstr_util_strdup_to_c(h->name);
3802 FAIL_IF(strcmp(name,
"Host") != 0);
3804 char *value = bstr_util_strdup_to_c(h->value);
3806 FAIL_IF(strcmp(value,
"www.google.com\rName: Value") != 0);
3818 static int HTPParserConfigTest01(
void)
3831 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3832 personality: Tomcat_6_0\n\
3837 - 192.168.10.0/24\n\
3838 personality: IIS_7_0\n\
3847 outputs =
ConfGetNode(
"libhtp.default-config.personality");
3858 FAIL_IF(strcmp(node->
name,
"apache-tomcat") != 0);
3865 FAIL_IF(strcmp(node2->
val,
"Tomcat_6_0") != 0);
3875 FAIL_IF(strcmp(n->
val,
"192.168.1.0/24") != 0);
3915 FAIL_IF(strcmp(n->
val,
"192.168.0.0/24") != 0);
3919 FAIL_IF(strcmp(n->
val,
"192.168.10.0/24") != 0);
3934 static int HTPParserConfigTest02(
void)
3947 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
3948 personality: Tomcat_6_0\n\
3953 - 192.168.10.0/24\n\
3954 personality: IIS_7_0\n\
3966 htp_cfg_t *htp = cfglist.
cfg;
3969 void *user_data = NULL;
3971 addr =
"192.168.10.42";
3972 FAIL_IF(inet_pton(AF_INET, addr, buf) != 1);
3976 htp = htp_cfg_rec->
cfg;
3982 FAIL_IF(inet_pton(AF_INET6, addr, buf) != 1);
3985 htp_cfg_rec = user_data;
3986 htp = htp_cfg_rec->
cfg;
3999 static int HTPParserConfigTest03(
void)
4002 uint8_t httpbuf1[] =
"POST / HTTP/1.0\r\nUser-Agent: Victor/1.0\r\n\r\nPost"
4004 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4020 address: [192.168.1.0/24, 127.0.0.0/8, \"::1\"]\n\
4021 personality: Tomcat_6_0\n\
4026 - 192.168.10.0/24\n\
4027 personality: IIS_7_0\n\
4038 const char *addr =
"192.168.10.42";
4040 memset(&ssn, 0,
sizeof(ssn));
4045 f->
proto = IPPROTO_TCP;
4048 htp_cfg_t *htp = cfglist.
cfg;
4051 void *user_data = NULL;
4056 htp = htp_cfg_rec->
cfg;
4063 for (u = 0; u < httplen1; u++) {
4066 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4067 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4068 else flags = STREAM_TOSERVER;
4077 FAIL_IF(HTPStateGetTxCnt(htp_state) != 2);
4079 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4083 tx = HTPStateGetTx(htp_state, 1);
4104 static int HTPParserDecodingTest01(
void)
4106 uint8_t httpbuf1[] =
4107 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4108 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4109 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4110 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4121 personality: Apache_2\n\
4129 const char *addr =
"4.3.2.1";
4130 memset(&ssn, 0,
sizeof(ssn));
4135 f->
proto = IPPROTO_TCP;
4140 for (uint32_t u = 0; u < httplen1; u++) {
4142 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4143 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4144 else flags = STREAM_TOSERVER;
4153 uint8_t ref1[] =
"/abc%2fdef";
4154 size_t reflen =
sizeof(ref1) - 1;
4156 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4166 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4167 reflen =
sizeof(ref2) - 1;
4169 tx = HTPStateGetTx(htp_state, 1);
4179 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4180 reflen =
sizeof(ref3) - 1;
4181 tx = HTPStateGetTx(htp_state, 2);
4202 static int HTPParserDecodingTest01a(
void)
4204 uint8_t httpbuf1[] =
"GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4205 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4206 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4207 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4218 personality: Apache_2\n\
4226 const char *addr =
"4.3.2.1";
4227 memset(&ssn, 0,
sizeof(ssn));
4232 f->
proto = IPPROTO_TCP;
4238 (STREAM_TOSERVER | STREAM_START | STREAM_EOF), httpbuf1, httplen1);
4244 uint8_t ref1[] =
"/abc%2fdef";
4245 size_t reflen =
sizeof(ref1) - 1;
4247 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4257 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4258 reflen =
sizeof(ref2) - 1;
4260 tx = HTPStateGetTx(htp_state, 1);
4270 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4271 reflen =
sizeof(ref3) - 1;
4272 tx = HTPStateGetTx(htp_state, 2);
4299 static int HTPParserDecodingTest02(
void)
4302 uint8_t httpbuf1[] =
4303 "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4304 "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4305 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4306 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4318 double-decode-path: no\n\
4319 double-decode-query: no\n\
4327 const char *addr =
"4.3.2.1";
4328 memset(&ssn, 0,
sizeof(ssn));
4333 f->
proto = IPPROTO_TCP;
4339 for (u = 0; u < httplen1; u++) {
4342 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4343 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4344 else flags = STREAM_TOSERVER;
4353 uint8_t ref1[] =
"/abc/def";
4354 size_t reflen =
sizeof(ref1) - 1;
4356 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4365 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4366 reflen =
sizeof(ref2) - 1;
4368 tx = HTPStateGetTx(htp_state, 1);
4378 uint8_t ref3[] =
"/abc/def?ghi%2fjkl";
4379 reflen =
sizeof(ref3) - 1;
4380 tx = HTPStateGetTx(htp_state, 2);
4406 static int HTPParserDecodingTest03(
void)
4409 uint8_t httpbuf1[] =
4410 "GET /abc%252fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"
4411 "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4412 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4424 double-decode-path: yes\n\
4425 double-decode-query: yes\n\
4433 const char *addr =
"4.3.2.1";
4434 memset(&ssn, 0,
sizeof(ssn));
4439 f->
proto = IPPROTO_TCP;
4445 for (u = 0; u < httplen1; u++) {
4448 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4449 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4450 else flags = STREAM_TOSERVER;
4459 uint8_t ref1[] =
"/abc/def";
4460 size_t reflen =
sizeof(ref1) - 1;
4462 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4472 uint8_t ref2[] =
"/abc/def?ghi/jkl";
4473 reflen =
sizeof(ref2) - 1;
4475 tx = HTPStateGetTx(htp_state, 1);
4498 static int HTPParserDecodingTest04(
void)
4501 uint8_t httpbuf1[] =
4502 "GET /abc/def?a=http://www.abc.com/ HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4503 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4515 double-decode-path: yes\n\
4516 double-decode-query: yes\n\
4524 const char *addr =
"4.3.2.1";
4525 memset(&ssn, 0,
sizeof(ssn));
4530 f->
proto = IPPROTO_TCP;
4536 for (u = 0; u < httplen1; u++) {
4539 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4540 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4541 else flags = STREAM_TOSERVER;
4550 uint8_t ref1[] =
"/abc/def?a=http://www.abc.com/";
4551 size_t reflen =
sizeof(ref1) - 1;
4553 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4576 static int HTPParserDecodingTest05(
void)
4579 uint8_t httpbuf1[] =
4580 "GET /index?id=\\\"<script>alert(document.cookie)</script> HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4581 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4593 double-decode-path: yes\n\
4594 double-decode-query: yes\n\
4602 const char *addr =
"4.3.2.1";
4603 memset(&ssn, 0,
sizeof(ssn));
4608 f->
proto = IPPROTO_TCP;
4614 for (u = 0; u < httplen1; u++) {
4617 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4618 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4619 else flags = STREAM_TOSERVER;
4628 uint8_t ref1[] =
"/index?id=\\\"<script>alert(document.cookie)</script>";
4629 size_t reflen =
sizeof(ref1) - 1;
4631 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4654 static int HTPParserDecodingTest06(
void)
4657 uint8_t httpbuf1[] =
4658 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4659 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4671 double-decode-path: yes\n\
4672 double-decode-query: yes\n\
4680 const char *addr =
"4.3.2.1";
4681 memset(&ssn, 0,
sizeof(ssn));
4686 f->
proto = IPPROTO_TCP;
4692 for (u = 0; u < httplen1; u++) {
4695 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4696 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4697 else flags = STREAM_TOSERVER;
4706 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port=+6000";
4707 size_t reflen =
sizeof(ref1) - 1;
4709 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4732 static int HTPParserDecodingTest07(
void)
4735 uint8_t httpbuf1[] =
4736 "GET /put.php?ip=1.2.3.4&port=+6000 HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n";
4737 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4749 double-decode-path: yes\n\
4750 double-decode-query: yes\n\
4751 query-plusspace-decode: yes\n\
4759 const char *addr =
"4.3.2.1";
4760 memset(&ssn, 0,
sizeof(ssn));
4765 f->
proto = IPPROTO_TCP;
4771 for (u = 0; u < httplen1; u++) {
4774 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4775 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4776 else flags = STREAM_TOSERVER;
4785 uint8_t ref1[] =
"/put.php?ip=1.2.3.4&port= 6000";
4786 size_t reflen =
sizeof(ref1) - 1;
4788 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4811 static int HTPParserDecodingTest08(
void)
4814 uint8_t httpbuf1[] =
4815 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4816 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4835 const char *addr =
"4.3.2.1";
4836 memset(&ssn, 0,
sizeof(ssn));
4841 f->
proto = IPPROTO_TCP;
4847 for (u = 0; u < httplen1; u++) {
4850 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4851 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4852 else flags = STREAM_TOSERVER;
4861 uint8_t ref1[] =
"/blah/";
4862 size_t reflen =
sizeof(ref1) - 1;
4864 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4887 static int HTPParserDecodingTest09(
void)
4890 uint8_t httpbuf1[] =
4891 "GET http://suricata-ids.org/blah/ HTTP/1.1\r\nHost: suricata-ids.org\r\n\r\n";
4892 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
4904 uri-include-all: true\n\
4912 const char *addr =
"4.3.2.1";
4913 memset(&ssn, 0,
sizeof(ssn));
4918 f->
proto = IPPROTO_TCP;
4924 for (u = 0; u < httplen1; u++) {
4927 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
4928 else if (u == (httplen1 - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
4929 else flags = STREAM_TOSERVER;
4938 uint8_t ref1[] =
"http://suricata-ids.org/blah/";
4939 size_t reflen =
sizeof(ref1) - 1;
4941 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
4963 static int HTPBodyReassemblyTest01(
void)
4966 memset(&htud, 0x00,
sizeof(htud));
4968 memset(&hstate, 0x00,
sizeof(hstate));
4970 memset(&flow, 0x00,
sizeof(flow));
4973 memset(&tx, 0,
sizeof(tx));
4978 uint8_t chunk1[] =
"--e5a320f21416a02493a0a6f561b1c494\r\nContent-Disposition: form-data; name=\"uploadfile\"; filename=\"D2GUef.jpg\"\r";
4979 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";
4986 const uint8_t *chunks_buffer = NULL;
4987 uint32_t chunks_buffer_len = 0;
4989 HtpRequestBodyReassemble(&htud, &chunks_buffer, &chunks_buffer_len);
4992 printf(
"REASSCHUNK START: \n");
4994 printf(
"REASSCHUNK END: \n");
4997 htud.
mime_state = SCMimeStateInit((
const uint8_t *)
"multipart/form-data; boundary=toto",
4998 strlen(
"multipart/form-data; boundary=toto"));
5001 HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len,
false);
5011 static int HTPSegvTest01(
void)
5014 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";
5015 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5023 double-decode-path: no\n\
5024 double-decode-query: no\n\
5025 request-body-limit: 0\n\
5026 response-body-limit: 0\n\
5039 memset(&ssn, 0,
sizeof(ssn));
5041 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5044 f->
proto = IPPROTO_TCP;
5049 SCLogDebug(
"\n>>>> processing chunk 1 <<<<\n");
5053 SCLogDebug(
"\n>>>> processing chunk 1 again <<<<\n");
5074 static int HTPParserTest14(
void)
5085 double-decode-path: no\n\
5086 double-decode-query: no\n\
5087 request-body-limit: 0\n\
5088 response-body-limit: 0\n\
5093 memset(&ssn, 0,
sizeof(ssn));
5103 memset(httpbuf, 0x00,
len);
5106 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5107 "Host: myhost.lan\r\n"
5108 "Connection: keep-alive\r\n"
5110 "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"
5111 "Referer: http://blah.lan/\r\n"
5112 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5114 size_t o = strlen(httpbuf);
5115 for ( ; o <
len - 4; o++) {
5118 httpbuf[
len - 4] =
'\r';
5119 httpbuf[
len - 3] =
'\n';
5120 httpbuf[
len - 2] =
'\r';
5121 httpbuf[
len - 1] =
'\n';
5127 f->
proto = IPPROTO_TCP;
5132 for (u = 0; u <
len; u++) {
5135 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5136 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5137 else flags = STREAM_TOSERVER;
5145 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5147 FAIL_IF(tx->request_method_number != HTP_M_GET);
5148 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
5170 static int HTPParserTest15(
void)
5173 char *httpbuf = NULL;
5184 double-decode-path: no\n\
5185 double-decode-query: no\n\
5186 request-body-limit: 0\n\
5187 response-body-limit: 0\n\
5188 meta-field-limit: 20000\n\
5192 memset(&ssn, 0,
sizeof(ssn));
5203 memset(httpbuf, 0x00,
len);
5206 strlcpy(httpbuf,
"GET /blah/ HTTP/1.1\r\n"
5207 "Host: myhost.lan\r\n"
5208 "Connection: keep-alive\r\n"
5210 "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"
5211 "Referer: http://blah.lan/\r\n"
5212 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5214 size_t o = strlen(httpbuf);
5215 for ( ; o <
len - 4; o++) {
5218 httpbuf[
len - 4] =
'\r';
5219 httpbuf[
len - 3] =
'\n';
5220 httpbuf[
len - 2] =
'\r';
5221 httpbuf[
len - 1] =
'\n';
5223 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5226 f->
proto = IPPROTO_TCP;
5232 for (u = 0; u <
len; u++) {
5235 if (u == 0)
flags = STREAM_TOSERVER|STREAM_START;
5236 else if (u == (
len - 1))
flags = STREAM_TOSERVER|STREAM_EOF;
5237 else flags = STREAM_TOSERVER;
5246 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5248 FAIL_IF(tx->request_method_number != HTP_M_GET);
5249 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
5268 static int HTPParserTest16(
void)
5275 memset(&ssn, 0,
sizeof(ssn));
5277 uint8_t httpbuf[] =
"GET\f/blah/\fHTTP/1.1\r\n"
5278 "Host: myhost.lan\r\n"
5279 "Connection: keep-alive\r\n"
5281 "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"
5282 "Referer: http://blah.lan/\r\n"
5283 "Accept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\n"
5284 "Cookie: blah\r\n\r\n";
5285 size_t len =
sizeof(httpbuf) - 1;
5287 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5290 f->
proto = IPPROTO_TCP;
5295 uint8_t
flags = STREAM_TOSERVER|STREAM_START|STREAM_EOF;
5303 htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
5305 FAIL_IF(tx->request_method_number != HTP_M_GET);
5306 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
5308 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
5328 static int HTPParserTest20(
void)
5331 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5332 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5333 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5334 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5335 uint8_t httpbuf2[] =
"NOTHTTP\r\nSOMEOTHERDATA";
5336 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5337 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5338 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5344 memset(&ssn, 0,
sizeof(ssn));
5346 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5349 f->
proto = IPPROTO_TCP;
5368 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5370 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
5373 FAIL_IF(tx->request_method_number != HTP_M_GET);
5374 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
5376 FAIL_IF(tx->response_status_number != 0);
5377 FAIL_IF(tx->response_protocol_number != -1);
5387 static int HTPParserTest21(
void)
5390 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5391 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5392 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5393 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5394 uint8_t httpbuf2[] =
"999 NOTHTTP REALLY\r\nSOMEOTHERDATA\r\n";
5395 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5396 uint8_t httpbuf3[] =
"STILLNOTHTTP\r\nSOMEMOREOTHERDATA";
5397 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
5403 memset(&ssn, 0,
sizeof(ssn));
5405 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5408 f->
proto = IPPROTO_TCP;
5427 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5429 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
5432 FAIL_IF(tx->request_method_number != HTP_M_GET);
5433 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
5435 FAIL_IF(tx->response_status_number != 0);
5436 FAIL_IF(tx->response_protocol_number != -1);
5446 static int HTPParserTest22(
void)
5449 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5450 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5451 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5452 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5453 uint8_t httpbuf2[] =
"\r\n0000=0000000/ASDF3_31.zip, 456723\r\n"
5454 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5455 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5461 memset(&ssn, 0,
sizeof(ssn));
5463 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5466 f->
proto = IPPROTO_TCP;
5481 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5483 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
5486 FAIL_IF(tx->request_method_number != HTP_M_GET);
5487 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
5489 FAIL_IF(tx->response_status_number != -0);
5490 FAIL_IF(tx->response_protocol_number != -1);
5500 static int HTPParserTest23(
void)
5503 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5504 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5505 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5506 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5507 uint8_t httpbuf2[] =
"HTTP0000=0000000/ASDF3_31.zip, 456723\r\n"
5508 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5509 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
5515 memset(&ssn, 0,
sizeof(ssn));
5517 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 1024, 80);
5520 f->
proto = IPPROTO_TCP;
5535 htp_tx_t *tx = HTPStateGetTx(http_state, 0);
5537 htp_header_t *h = htp_table_get_index(tx->request_headers, 0, NULL);
5540 FAIL_IF(tx->request_method_number != HTP_M_GET);
5541 FAIL_IF(tx->request_protocol_number != HTP_PROTOCOL_1_1);
5543 FAIL_IF(tx->response_status_number != -1);
5544 FAIL_IF(tx->response_protocol_number != -2);
5554 static int HTPParserTest24(
void)
5557 uint8_t httpbuf1[] =
"GET /ld/index.php?id=412784631&cid=0064&version=4&"
5558 "name=try HTTP/1.1\r\nAccept: */*\r\nUser-Agent: "
5559 "LD-agent\r\nHost: 209.205.196.16\r\n\r\n";
5560 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
5561 uint8_t httpbuf2[] =
"HTTP/1.0 0000=0000000/ASDF3_31.zip, 456723\r\n"
5562 "AAAAAA_0000=0000000/AAAAAAAA.zip,46725\r\n";
5563 uint32_t httplen2 =
sizeof(httpbuf2) - 1;