From: Anoop Saldanha Date: Fri, 3 May 2013 04:33:48 +0000 (+0530) Subject: Track transaction progress separately for each direction in libhtp. X-Git-Tag: suricata-2.0beta1~142 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fd7927ecd6ae4ac249a2849350ad0f8ea5dfef59;p=thirdparty%2Fsuricata.git 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. --- diff --git a/libhtp/htp/htp.h b/libhtp/htp/htp.h index dabdb47ccb..01465fa423 100644 --- a/libhtp/htp/htp.h +++ b/libhtp/htp/htp.h @@ -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); diff --git a/libhtp/htp/htp_request.c b/libhtp/htp/htp_request.c index 27ecbd826f..f7d3d89eaf 100644 --- a/libhtp/htp/htp_request.c +++ b/libhtp/htp/htp_request.c @@ -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 diff --git a/libhtp/htp/htp_response.c b/libhtp/htp/htp_response.c index 0cc7e0e4ec..3a0a24432e 100644 --- a/libhtp/htp/htp_response.c +++ b/libhtp/htp/htp_response.c @@ -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 diff --git a/libhtp/htp/htp_util.c b/libhtp/htp/htp_util.c index 9363001a45..6c6acd479e 100644 --- a/libhtp/htp/htp_util.c +++ b/libhtp/htp/htp_util.c @@ -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);