Track transaction progress separately for each direction in libhtp.

Currently libhtp tracks it using the same var.  This can lead to misleading
states, since a response can come in without a full request.
pull/366/merge
Anoop Saldanha 12 years ago committed by Victor Julien
parent 6dcde9d7e9
commit fd7927ecd6

@ -934,7 +934,7 @@ struct htp_tx_t {
unsigned int flags;
/** Transaction progress. Look for the TX_PROGRESS_* constants for more information. */
unsigned int progress;
unsigned int progress[2];
};
/** This structure is used to pass transaction data to callbacks. */
@ -1156,7 +1156,7 @@ void fprint_raw_data(FILE *stream, const char *name, unsigned char *data, size_t
char *htp_connp_in_state_as_string(htp_connp_t *connp);
char *htp_connp_out_state_as_string(htp_connp_t *connp);
char *htp_tx_progress_as_string(htp_tx_t *tx);
char *htp_tx_progress_as_string(htp_tx_t *tx, int direction);
bstr *htp_unparse_uri_noencode(htp_uri_t *uri);

@ -33,7 +33,7 @@ int htp_connp_REQ_CONNECT_CHECK(htp_connp_t *connp) {
if (connp->in_tx->request_method_number == M_CONNECT) {
connp->in_state = htp_connp_REQ_CONNECT_WAIT_RESPONSE;
connp->in_status = STREAM_STATE_DATA_OTHER;
connp->in_tx->progress = TX_PROGRESS_WAIT;
connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
return HTP_DATA_OTHER;
}
@ -57,7 +57,7 @@ int htp_connp_REQ_CONNECT_CHECK(htp_connp_t *connp) {
int htp_connp_REQ_CONNECT_WAIT_RESPONSE(htp_connp_t *connp) {
// Check that we saw the response line of the current
// inbound transaction.
if (connp->in_tx->progress <= TX_PROGRESS_RES_LINE) {
if (connp->in_tx->progress[0] <= TX_PROGRESS_RES_LINE) {
return HTP_DATA_OTHER;
}
@ -185,7 +185,7 @@ int htp_connp_REQ_BODY_CHUNKED_LENGTH(htp_connp_t *connp) {
} else if (connp->in_chunked_length == 0) {
// End of data
connp->in_state = htp_connp_REQ_HEADERS;
connp->in_tx->progress = TX_PROGRESS_REQ_TRAILER;
connp->in_tx->progress[0] = TX_PROGRESS_REQ_TRAILER;
} else {
// Invalid chunk length
htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
@ -249,7 +249,7 @@ int htp_connp_REQ_BODY_IDENTITY(htp_connp_t *connp) {
// Done
connp->in_state = htp_connp_REQ_IDLE;
connp->in_tx->progress = TX_PROGRESS_WAIT;
connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
return HTP_OK;
}
@ -300,7 +300,7 @@ int htp_connp_REQ_BODY_DETERMINE(htp_connp_t *connp) {
}
connp->in_state = htp_connp_REQ_BODY_CHUNKED_LENGTH;
connp->in_tx->progress = TX_PROGRESS_REQ_BODY;
connp->in_tx->progress[0] = TX_PROGRESS_REQ_BODY;
} else
// Next check for the presence of the Content-Length header
if (cl != NULL && cl->value != NULL) {
@ -330,17 +330,17 @@ int htp_connp_REQ_BODY_DETERMINE(htp_connp_t *connp) {
if (connp->in_content_length != 0) {
connp->in_state = htp_connp_REQ_BODY_IDENTITY;
connp->in_tx->progress = TX_PROGRESS_REQ_BODY;
connp->in_tx->progress[0] = TX_PROGRESS_REQ_BODY;
} else {
connp->in_state = htp_connp_REQ_IDLE;
connp->in_tx->progress = TX_PROGRESS_WAIT;
connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
}
}
} else {
// This request does not have a body, which
// means that we're done with it
connp->in_state = htp_connp_REQ_IDLE;
connp->in_tx->progress = TX_PROGRESS_WAIT;
connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
}
// Host resolution
@ -442,7 +442,7 @@ int htp_connp_REQ_HEADERS(htp_connp_t *connp) {
}
// Move onto the next processing phase
if (connp->in_tx->progress == TX_PROGRESS_REQ_HEADERS) {
if (connp->in_tx->progress[0] == TX_PROGRESS_REQ_HEADERS) {
// Determine if this request has a body
//connp->in_state = htp_connp_REQ_BODY_DETERMINE;
connp->in_state = htp_connp_REQ_CONNECT_CHECK;
@ -457,7 +457,7 @@ int htp_connp_REQ_HEADERS(htp_connp_t *connp) {
// We've completed parsing this request
connp->in_state = htp_connp_REQ_IDLE;
connp->in_tx->progress = TX_PROGRESS_WAIT;
connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
}
return HTP_OK;
@ -544,11 +544,11 @@ int htp_connp_REQ_PROTOCOL(htp_connp_t *connp) {
if (connp->in_tx->protocol_is_simple == 0) {
// Switch to request header parsing.
connp->in_state = htp_connp_REQ_HEADERS;
connp->in_tx->progress = TX_PROGRESS_REQ_HEADERS;
connp->in_tx->progress[0] = TX_PROGRESS_REQ_HEADERS;
} else {
// We're done with this request.
connp->in_state = htp_connp_REQ_IDLE;
connp->in_tx->progress = TX_PROGRESS_WAIT;
connp->in_tx->progress[0] = TX_PROGRESS_WAIT;
}
return HTP_OK;
@ -779,7 +779,7 @@ int htp_connp_REQ_IDLE(htp_connp_t * connp) {
// Change state into request line parsing
connp->in_state = htp_connp_REQ_LINE;
connp->in_tx->progress = TX_PROGRESS_REQ_LINE;
connp->in_tx->progress[0] = TX_PROGRESS_REQ_LINE;
return HTP_OK;
}
@ -854,7 +854,7 @@ int htp_connp_req_data(htp_connp_t *connp, htp_time_t timestamp, unsigned char *
#ifdef HTP_DEBUG
fprintf(stderr, "htp_connp_req_data: in state=%s, progress=%s\n",
htp_connp_in_state_as_string(connp),
htp_tx_progress_as_string(connp->in_tx));
htp_tx_progress_as_string(connp->in_tx, 0));
#endif
// Return if there's been an error

@ -149,7 +149,7 @@ int htp_connp_RES_BODY_CHUNKED_LENGTH(htp_connp_t *connp) {
} else if (connp->out_chunked_length == 0) {
// End of data
connp->out_state = htp_connp_RES_HEADERS;
connp->out_tx->progress = TX_PROGRESS_RES_TRAILER;
connp->out_tx->progress[1] = TX_PROGRESS_RES_TRAILER;
} else {
// Invalid chunk length
htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
@ -201,7 +201,7 @@ int htp_connp_RES_BODY_IDENTITY(htp_connp_t *connp) {
// end of the response body (and the end of the transaction).
if ((connp->out_content_length == -1) && (connp->out_status == STREAM_STATE_CLOSED)) {
connp->out_state = htp_connp_RES_IDLE;
connp->out_tx->progress = TX_PROGRESS_DONE;
connp->out_tx->progress[1] = TX_PROGRESS_DONE;
return HTP_OK;
} else {
@ -237,7 +237,7 @@ int htp_connp_RES_BODY_IDENTITY(htp_connp_t *connp) {
// Done
connp->out_state = htp_connp_RES_IDLE;
connp->out_tx->progress = TX_PROGRESS_DONE;
connp->out_tx->progress[1] = TX_PROGRESS_DONE;
return HTP_OK;
}
@ -270,7 +270,7 @@ int htp_connp_RES_BODY_DETERMINE(htp_connp_t *connp) {
{
connp->out_status = STREAM_STATE_TUNNEL;
connp->out_state = htp_connp_RES_IDLE;
connp->out_tx->progress = TX_PROGRESS_DONE;
connp->out_tx->progress[1] = TX_PROGRESS_DONE;
return HTP_OK;
}
@ -287,7 +287,7 @@ int htp_connp_RES_BODY_DETERMINE(htp_connp_t *connp) {
table_clear(connp->out_tx->response_headers);
connp->out_state = htp_connp_RES_LINE;
connp->out_tx->progress = TX_PROGRESS_RES_LINE;
connp->out_tx->progress[1] = TX_PROGRESS_RES_LINE;
connp->out_tx->seen_100continue++;
return HTP_OK;
@ -347,7 +347,7 @@ int htp_connp_RES_BODY_DETERMINE(htp_connp_t *connp) {
}
connp->out_state = htp_connp_RES_BODY_CHUNKED_LENGTH;
connp->out_tx->progress = TX_PROGRESS_RES_BODY;
connp->out_tx->progress[1] = TX_PROGRESS_RES_BODY;
}// 3. If a Content-Length header field (section 14.14) is present, its
// value in bytes represents the length of the message-body.
else if (cl != NULL) {
@ -371,10 +371,10 @@ int htp_connp_RES_BODY_DETERMINE(htp_connp_t *connp) {
if (connp->out_content_length != 0) {
connp->out_state = htp_connp_RES_BODY_IDENTITY;
connp->out_tx->progress = TX_PROGRESS_RES_BODY;
connp->out_tx->progress[1] = TX_PROGRESS_RES_BODY;
} else {
connp->out_state = htp_connp_RES_IDLE;
connp->out_tx->progress = TX_PROGRESS_DONE;
connp->out_tx->progress[1] = TX_PROGRESS_DONE;
}
}
} else {
@ -399,7 +399,7 @@ int htp_connp_RES_BODY_DETERMINE(htp_connp_t *connp) {
// cannot be used to indicate the end of a request body, since that
// would leave no possibility for the server to send back a response.)
connp->out_state = htp_connp_RES_BODY_IDENTITY;
connp->out_tx->progress = TX_PROGRESS_RES_BODY;
connp->out_tx->progress[1] = TX_PROGRESS_RES_BODY;
}
}
@ -472,7 +472,7 @@ int htp_connp_RES_HEADERS(htp_connp_t *connp) {
connp->out_header_line = NULL;
// We've seen all response headers
if (connp->out_tx->progress == TX_PROGRESS_RES_HEADERS) {
if (connp->out_tx->progress[1] == TX_PROGRESS_RES_HEADERS) {
// Determine if this response has a body
connp->out_state = htp_connp_RES_BODY_DETERMINE;
} else {
@ -636,7 +636,7 @@ int htp_connp_RES_LINE(htp_connp_t *connp) {
// Move on to the next phase.
connp->out_state = htp_connp_RES_HEADERS;
connp->out_tx->progress = TX_PROGRESS_RES_HEADERS;
connp->out_tx->progress[1] = TX_PROGRESS_RES_HEADERS;
return HTP_OK;
}
@ -666,7 +666,7 @@ int htp_connp_RES_IDLE(htp_connp_t * connp) {
connp->out_decompressor = NULL;
}
connp->out_tx->progress = TX_PROGRESS_DONE;
connp->out_tx->progress[1] = TX_PROGRESS_DONE;
// Run hook RESPONSE
int rc = hook_run_all(connp->cfg->hook_response, connp);
@ -722,10 +722,10 @@ int htp_connp_RES_IDLE(htp_connp_t * connp) {
if (connp->out_tx->protocol_is_simple) {
connp->out_tx->response_transfer_coding = IDENTITY;
connp->out_state = htp_connp_RES_BODY_IDENTITY;
connp->out_tx->progress = TX_PROGRESS_RES_BODY;
connp->out_tx->progress[1] = TX_PROGRESS_RES_BODY;
} else {
connp->out_state = htp_connp_RES_LINE;
connp->out_tx->progress = TX_PROGRESS_RES_LINE;
connp->out_tx->progress[1] = TX_PROGRESS_RES_LINE;
}
return HTP_OK;
@ -796,7 +796,7 @@ int htp_connp_res_data(htp_connp_t *connp, htp_time_t timestamp, unsigned char *
#ifdef HTP_DEBUG
fprintf(stderr, "htp_connp_res_data: out state=%s, progress=%s\n",
htp_connp_out_state_as_string(connp),
htp_tx_progress_as_string(connp->out_tx));
htp_tx_progress_as_string(connp->out_tx, 1));
#endif
// Return if there's been an error
// or if we've run out of data. We are relying

@ -1984,10 +1984,10 @@ char *htp_connp_out_state_as_string(htp_connp_t *connp) {
/**
*
*/
char *htp_tx_progress_as_string(htp_tx_t *tx) {
char *htp_tx_progress_as_string(htp_tx_t *tx, int direction) {
if (tx == NULL) return "NULL";
switch (tx->progress) {
switch ((direction == 0) ? tx->progress[0] : tx->progress[1]) {
case TX_PROGRESS_NEW:
return "NEW";
case TX_PROGRESS_REQ_LINE:
@ -2171,7 +2171,7 @@ bstr *htp_tx_generate_request_headers_raw(htp_tx_t *tx) {
*/
bstr *htp_tx_get_request_headers_raw(htp_tx_t *tx) {
// Check that we are not called too early
if (tx->progress < TX_PROGRESS_REQ_HEADERS) return NULL;
if (tx->progress[0] < TX_PROGRESS_REQ_HEADERS) return NULL;
if (tx->request_headers_raw == NULL) {
tx->request_headers_raw = htp_tx_generate_request_headers_raw(tx);
@ -2241,7 +2241,7 @@ bstr *htp_tx_generate_response_headers_raw(htp_tx_t *tx) {
*/
bstr *htp_tx_get_response_headers_raw(htp_tx_t *tx) {
// Check that we are not called too early
if (tx->progress < TX_PROGRESS_RES_HEADERS) return NULL;
if (tx->progress[1] < TX_PROGRESS_RES_HEADERS) return NULL;
if (tx->response_headers_raw == NULL) {
tx->response_headers_raw = htp_tx_generate_response_headers_raw(tx);

Loading…
Cancel
Save