From: Victor Julien Date: Thu, 22 Mar 2012 11:33:57 +0000 (+0100) Subject: libhtp: update to sync with upstream 0.2.x X-Git-Tag: suricata-1.3beta1~64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef52ba8f57bb4f8c10010f2a913e43133852a4ca;p=thirdparty%2Fsuricata.git libhtp: update to sync with upstream 0.2.x Patches applied are: commit 85f5bbc39dda2eaf03ccb6111cbf5daf1c7b75f9 Author: Craig Forbes Date: Wed Mar 21 16:45:04 2012 +0000 Backport of STREAM_STATE_TUNNEL fix to 0.2.x. Return STREAM_STATE_TUNNEL after entering a tunnel. commit cfbe28cd4ddde6d77c5b0d5935c8717834971441 Author: Craig Forbes Date: Wed Feb 29 16:52:44 2012 +0000 Backport of the fix for HTP_AMBIGUOUS_HOST flag. The flag is only set when the URI host on the request line is different than the value in the Host: request header. Resolves https://github.com/ironbee/libhtp/issues/20 commit 196dfb1c8b7a5996389c719e2c912163c5607916 Author: Brian Rectanus Date: Wed Feb 8 08:35:46 2012 -0600 Add missing function declaration in header. commit 7878fec818167fcdf7c8c4852ac0dafa1ae445f1 Author: Brian Rectanus Date: Wed Feb 8 08:35:07 2012 -0600 Revert part of previous patch, which was invalid. commit bafef3d4cbfc307960677c6bd682ae195fe986cd Author: Brian Rectanus Date: Wed Feb 8 08:36:06 2012 -0600 Update version to next dev release. commit 62cfdb41ba84f2666c7526e2e5d9e10ab8e220f1 Author: William Metcalf Date: Wed Feb 1 13:19:48 2012 -0600 Many thanks to Will, Brian and Craig. --- diff --git a/libhtp/htp/bstr.c b/libhtp/htp/bstr.c index 42ce78057b..9cf330cfb3 100644 --- a/libhtp/htp/bstr.c +++ b/libhtp/htp/bstr.c @@ -350,6 +350,38 @@ int bstr_cmp_ex(char *s1, size_t l1, char *s2, size_t l2) { } } +/** + * Case-insensitive comparison of two memory regions. + * + * @param s1 + * @param l1 + * @param s2 + * @param l2 + * @return 0 if the memory regions are identical, -1 or +1 if they're not + */ +int bstr_cmp_nocase_ex(char *s1, size_t l1, char *s2, size_t l2) { + size_t p1 = 0, p2 = 0; + + while ((p1 < l1) && (p2 < l2)) { + if (tolower((int)s1[p1]) != tolower((int)s2[p2])) { + // Difference + return (tolower((int)s1[p1]) < tolower((int)s2[p2])) ? -1 : 1; + } + + p1++; + p2++; + } + + if ((p1 == l2) && (p2 == l1)) { + // They're identical + return 0; + } else { + // One string is shorter + if (p1 == l1) return -1; + else return 1; + } +} + /** * Compare a bstring with a NUL-terminated string. * @@ -372,6 +404,17 @@ int bstr_cmp(bstr *b1, bstr *b2) { return bstr_cmp_ex(bstr_ptr(b1), bstr_len(b1), bstr_ptr(b2), bstr_len(b2)); } +/** + * Case-insensitive comparison two bstrings. + * + * @param b1 + * @param b2 + * @return 0, -1 or +1 + */ +int bstr_cmp_nocase(bstr *b1, bstr *b2) { + return bstr_cmp_nocase_ex(bstr_ptr(b1), bstr_len(b1), bstr_ptr(b2), bstr_len(b2)); +} + /** * Convert bstring to lowercase. * diff --git a/libhtp/htp/bstr.h b/libhtp/htp/bstr.h index d6423887dc..9122249b3f 100644 --- a/libhtp/htp/bstr.h +++ b/libhtp/htp/bstr.h @@ -42,6 +42,7 @@ int bstr_rchr(bstr *, int); int bstr_cmpc(bstr *, char *); int bstr_cmp(bstr *, bstr *); +int bstr_cmp_nocase(bstr *, bstr *); bstr *bstr_dup_lower(bstr *); bstr *bstr_tolowercase(bstr *); diff --git a/libhtp/htp/htp.h b/libhtp/htp/htp.h index 765aeddf3b..38c4751885 100644 --- a/libhtp/htp/htp.h +++ b/libhtp/htp/htp.h @@ -41,7 +41,7 @@ typedef struct htp_urldecoder_t htp_urldecoder_t; // -- Defines ------------------------------------------------------------------------------------- -#define HTP_BASE_VERSION_TEXT "0.2.7" +#define HTP_BASE_VERSION_TEXT "0.2.8-dev" #define HTP_ERROR -1 #define HTP_OK 0 @@ -1003,7 +1003,7 @@ void htp_config_set_path_compress_separators(htp_cfg_t *cfg, int compress_separa void htp_config_set_path_control_char_handling(htp_cfg_t *cfg, int control_char_handling); void htp_config_set_path_convert_utf8(htp_cfg_t *cfg, int convert_utf8); void htp_config_set_path_decode_separators(htp_cfg_t *cfg, int backslash_separators); -void htp_config_set_path_decode_separators(htp_cfg_t *cfg, int decode_u_encoding); +void htp_config_set_path_decode_u_encoding(htp_cfg_t *cfg, int decode_u_encoding); void htp_config_set_path_invalid_encoding_handling(htp_cfg_t *cfg, int invalid_encoding_handling); void htp_config_set_path_invalid_utf8_handling(htp_cfg_t *cfg, int invalid_utf8_handling); void htp_config_set_path_nul_encoded_handling(htp_cfg_t *cfg, int nul_encoded_handling); @@ -1024,7 +1024,7 @@ void htp_connp_destroy_all(htp_connp_t *connp); void htp_connp_set_user_data(htp_connp_t *connp, void *user_data); void *htp_connp_get_user_data(htp_connp_t *connp); -htp_conn_t *htp_conn_create(); +htp_conn_t *htp_conn_create(htp_connp_t *connp); void htp_conn_destroy(htp_conn_t *conn); int htp_conn_remove_tx(htp_conn_t *conn, htp_tx_t *tx); diff --git a/libhtp/htp/htp_config.c b/libhtp/htp/htp_config.c index 0a9aba1bd0..bd2c3fe802 100644 --- a/libhtp/htp/htp_config.c +++ b/libhtp/htp/htp_config.c @@ -158,9 +158,11 @@ htp_cfg_t *htp_config_create() { * @return A copy of the configuration structure. */ htp_cfg_t *htp_config_copy(htp_cfg_t *cfg) { - htp_cfg_t *copy = calloc(1, sizeof(htp_cfg_t)); + htp_cfg_t *copy = malloc(sizeof(htp_cfg_t)); if (copy == NULL) return NULL; + *copy = *cfg; + // Create copies of the hooks' structures if (cfg->hook_transaction_start != NULL) { copy->hook_transaction_start = hook_copy(cfg->hook_transaction_start); diff --git a/libhtp/htp/htp_connection_parser.c b/libhtp/htp/htp_connection_parser.c index 7bb0793940..5bd6c36e83 100644 --- a/libhtp/htp/htp_connection_parser.c +++ b/libhtp/htp/htp_connection_parser.c @@ -272,3 +272,7 @@ void htp_connp_open(htp_connp_t *connp, const char *remote_addr, int remote_port void htp_connp_set_user_data(htp_connp_t *connp, void *user_data) { connp->user_data = user_data; } + +void *htp_connp_get_user_data(htp_connp_t *connp) { + return(connp->user_data); +} diff --git a/libhtp/htp/htp_request.c b/libhtp/htp/htp_request.c index 1513a9cb59..57f747de34 100644 --- a/libhtp/htp/htp_request.c +++ b/libhtp/htp/htp_request.c @@ -358,8 +358,8 @@ int htp_connp_REQ_BODY_DETERMINE(htp_connp_t *connp) { // There is no host information in the URI. Place the // hostname from the headers into the parsed_uri structure. htp_replace_hostname(connp, connp->in_tx->parsed_uri, h->value); - } else { - // The host information is present both in the + } else if (bstr_cmp_nocase(h->value, connp->in_tx->parsed_uri->hostname) != 0) { + // The host information is different in the // headers and the URI. The HTTP RFC states that // we should ignore the headers copy. connp->in_tx->flags |= HTP_AMBIGUOUS_HOST; @@ -787,6 +787,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: returning STREAM_STATE_DATA (previous error)\n"); #endif + return STREAM_STATE_ERROR; } @@ -800,6 +801,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: returning STREAM_STATE_DATA (zero-length chunk)\n"); #endif + return STREAM_STATE_ERROR; } @@ -816,9 +818,9 @@ int htp_connp_req_data(htp_connp_t *connp, htp_time_t timestamp, unsigned char * // mode (which it would be after an initial CONNECT transaction). if (connp->in_status == STREAM_STATE_TUNNEL) { #ifdef HTP_DEBUG - fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_DATA (tunnel)\n"); + fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_TUNNEL\n"); #endif - return STREAM_STATE_DATA; + return STREAM_STATE_TUNNEL; } // Invoke a processor, in a loop, until an error @@ -837,12 +839,21 @@ int htp_connp_req_data(htp_connp_t *connp, htp_time_t timestamp, unsigned char * // on processors to add error messages, so we'll // keep quiet here. int rc = connp->in_state(connp); - if (rc != HTP_OK) { + if (rc == HTP_OK) { + if (connp->in_status == STREAM_STATE_TUNNEL) { + #ifdef HTP_DEBUG + fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_TUNNEL\n"); + #endif + + return STREAM_STATE_TUNNEL; + } + } else { // Do we need more data? if (rc == HTP_DATA) { #ifdef HTP_DEBUG fprintf(stderr, "htp_connp_req_data: returning STREAM_STATE_DATA\n"); #endif + return STREAM_STATE_DATA; } diff --git a/libhtp/htp/htp_response.c b/libhtp/htp/htp_response.c index d93d0e813f..8a69e9c2de 100644 --- a/libhtp/htp/htp_response.c +++ b/libhtp/htp/htp_response.c @@ -726,6 +726,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: returning STREAM_STATE_DATA (previous error)\n"); #endif + return STREAM_STATE_ERROR; } @@ -739,6 +740,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: returning STREAM_STATE_DATA (zero-length chunk)\n"); #endif + return STREAM_STATE_ERROR; } @@ -754,9 +756,9 @@ int htp_connp_res_data(htp_connp_t *connp, htp_time_t timestamp, unsigned char * // mode (which it would be after an initial CONNECT transaction. if (connp->out_status == STREAM_STATE_TUNNEL) { #ifdef HTP_DEBUG - fprintf(stderr, "htp_connp_res_data: returning STREAM_STATE_DATA (tunnel)\n"); + fprintf(stderr, "htp_connp_res_data: returning STREAM_STATE_TUNNEL\n"); #endif - return STREAM_STATE_DATA; + return STREAM_STATE_TUNNEL; } // Invoke a processor, in a loop, until an error @@ -774,7 +776,15 @@ int htp_connp_res_data(htp_connp_t *connp, htp_time_t timestamp, unsigned char * // on processors to add error messages, so we'll // keep quiet here. int rc = connp->out_state(connp); - if (rc != HTP_OK) { + if (rc == HTP_OK) { + if (connp->out_status == STREAM_STATE_TUNNEL) { + #ifdef HTP_DEBUG + fprintf(stderr, "htp_connp_res_data: returning STREAM_STATE_TUNNEL\n"); + #endif + + return STREAM_STATE_TUNNEL; + } + } else { // Do we need more data? if (rc == HTP_DATA) { return STREAM_STATE_DATA;