]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Track transaction progress separately for each direction in libhtp.
authorAnoop Saldanha <anoopsaldanha@gmail.com>
Fri, 3 May 2013 04:33:48 +0000 (10:03 +0530)
committerVictor Julien <victor@inliniac.net>
Fri, 17 May 2013 09:07:12 +0000 (11:07 +0200)
Currently libhtp tracks it using the same var.  This can lead to misleading
states, since a response can come in without a full request.

libhtp/htp/htp.h
libhtp/htp/htp_request.c
libhtp/htp/htp_response.c
libhtp/htp/htp_util.c

index dabdb47ccb7d3a9e9b4ba67f2ce98cb731fbc27f..01465fa423d4c9baac56a0be05c0957b4af09f76 100644 (file)
@@ -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);
 
index 27ecbd826f587767fcf1c3879d14053d01252352..f7d3d89eaf42eb4410eaddfa69e69392b03aab29 100644 (file)
@@ -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
index 0cc7e0e4ec21d6022caec8519b079341cf34fd5f..3a0a24432e7003a51c784f040dffec051e507284 100644 (file)
@@ -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
index 9363001a4586c8c65c0291fc838c2402e6025a19..6c6acd479e0c9f5047fae6cf607207c599213c15 100644 (file)
@@ -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);