HTP
0.3
|
00001 /*************************************************************************** 00002 * Copyright (c) 2009-2010, Open Information Security Foundation 00003 * Copyright (c) 2009-2012, Qualys, Inc. 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are 00008 * met: 00009 * 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * * Neither the name of the Qualys, Inc. nor the names of its 00016 * contributors may be used to endorse or promote products derived from 00017 * this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00020 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00021 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00022 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00023 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00025 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00026 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00027 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00029 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 ***************************************************************************/ 00031 00037 #ifndef _HTP_H 00038 #define _HTP_H 00039 00040 typedef struct htp_cfg_t htp_cfg_t; 00041 typedef struct htp_conn_t htp_conn_t; 00042 typedef struct htp_connp_t htp_connp_t; 00043 typedef struct htp_file_t htp_file_t; 00044 typedef struct htp_file_data_t htp_file_data_t; 00045 typedef struct htp_header_t htp_header_t; 00046 typedef struct htp_header_line_t htp_header_line_t; 00047 typedef struct htp_log_t htp_log_t; 00048 typedef struct htp_tx_data_t htp_tx_data_t; 00049 typedef struct htp_tx_t htp_tx_t; 00050 typedef struct htp_uri_t htp_uri_t; 00051 00052 #include <ctype.h> 00053 #include <iconv.h> 00054 #include <stdarg.h> 00055 #include <stddef.h> 00056 #include <stdio.h> 00057 #include <stdint.h> 00058 #include <stdlib.h> 00059 #include <string.h> 00060 #include <sys/time.h> 00061 00062 #include "bstr.h" 00063 #include "dslib.h" 00064 #include "hooks.h" 00065 #include "htp_decompressors.h" 00066 #include "htp_urlencoded.h" 00067 #include "htp_multipart.h" 00068 00069 // -- Defines ------------------------------------------------------------------------------------- 00070 00071 #define HTP_BASE_VERSION_TEXT "0.3.0" 00072 00073 #define HTP_ERROR -1 00074 #define HTP_OK 0 00075 #define HTP_DATA 1 00076 #define HTP_DATA_OTHER 2 00077 #define HTP_DECLINED 3 00078 00079 #define PROTOCOL_UNKNOWN -1 00080 #define HTTP_0_9 9 00081 #define HTTP_1_0 100 00082 #define HTTP_1_1 101 00083 00084 #define HTP_LOG_MARK __FILE__,__LINE__ 00085 00086 #define HTP_LOG_ERROR 1 00087 #define HTP_LOG_WARNING 2 00088 #define HTP_LOG_NOTICE 3 00089 #define HTP_LOG_INFO 4 00090 #define HTP_LOG_DEBUG 5 00091 #define HTP_LOG_DEBUG2 6 00092 00093 #define HTP_HEADER_MISSING_COLON 1 00094 #define HTP_HEADER_INVALID_NAME 2 00095 #define HTP_HEADER_LWS_AFTER_FIELD_NAME 3 00096 #define HTP_LINE_TOO_LONG_HARD 4 00097 #define HTP_LINE_TOO_LONG_SOFT 5 00098 00099 #define HTP_HEADER_LIMIT_HARD 18000 00100 #define HTP_HEADER_LIMIT_SOFT 9000 00101 00102 #define HTP_VALID_STATUS_MIN 100 00103 #define HTP_VALID_STATUS_MAX 999 00104 00105 #define LOG_NO_CODE 0 00106 00107 #define CR '\r' 00108 #define LF '\n' 00109 00110 #define M_UNKNOWN -1 00111 00112 // The following request method are defined in Apache 2.2.13, in httpd.h. 00113 #define M_GET 0 00114 #define M_PUT 1 00115 #define M_POST 2 00116 #define M_DELETE 3 00117 #define M_CONNECT 4 00118 #define M_OPTIONS 5 00119 #define M_TRACE 6 00120 #define M_PATCH 7 00121 #define M_PROPFIND 8 00122 #define M_PROPPATCH 9 00123 #define M_MKCOL 10 00124 #define M_COPY 11 00125 #define M_MOVE 12 00126 #define M_LOCK 13 00127 #define M_UNLOCK 14 00128 #define M_VERSION_CONTROL 15 00129 #define M_CHECKOUT 16 00130 #define M_UNCHECKOUT 17 00131 #define M_CHECKIN 18 00132 #define M_UPDATE 19 00133 #define M_LABEL 20 00134 #define M_REPORT 21 00135 #define M_MKWORKSPACE 22 00136 #define M_MKACTIVITY 23 00137 #define M_BASELINE_CONTROL 24 00138 #define M_MERGE 25 00139 #define M_INVALID 26 00140 00141 // Interestingly, Apache does not define M_HEAD 00142 #define M_HEAD 1000 00143 00144 #define HTP_FIELD_UNPARSEABLE 0x000001 00145 #define HTP_FIELD_INVALID 0x000002 00146 #define HTP_FIELD_FOLDED 0x000004 00147 #define HTP_FIELD_REPEATED 0x000008 00148 #define HTP_FIELD_LONG 0x000010 00149 #define HTP_FIELD_NUL_BYTE 0x000020 00150 #define HTP_REQUEST_SMUGGLING 0x000040 00151 #define HTP_INVALID_FOLDING 0x000080 00152 #define HTP_INVALID_CHUNKING 0x000100 00153 #define HTP_MULTI_PACKET_HEAD 0x000200 00154 #define HTP_HOST_MISSING 0x000400 00155 #define HTP_AMBIGUOUS_HOST 0x000800 00156 #define HTP_PATH_ENCODED_NUL 0x001000 00157 #define HTP_PATH_INVALID_ENCODING 0x002000 00158 #define HTP_PATH_INVALID 0x004000 00159 #define HTP_PATH_OVERLONG_U 0x008000 00160 #define HTP_PATH_ENCODED_SEPARATOR 0x010000 00161 00162 #define HTP_PATH_UTF8_VALID 0x020000 /* At least one valid UTF-8 character and no invalid ones */ 00163 #define HTP_PATH_UTF8_INVALID 0x040000 00164 #define HTP_PATH_UTF8_OVERLONG 0x080000 00165 #define HTP_PATH_FULLWIDTH_EVASION 0x100000 /* Range U+FF00 - U+FFFF detected */ 00166 00167 #define HTP_STATUS_LINE_INVALID 0x200000 00168 00169 #define PIPELINED_CONNECTION 1 00170 00171 #define HTP_SERVER_MINIMAL 0 00172 #define HTP_SERVER_GENERIC 1 00173 #define HTP_SERVER_IDS 2 00174 #define HTP_SERVER_IIS_4_0 4 /* Windows NT 4.0 */ 00175 #define HTP_SERVER_IIS_5_0 5 /* Windows 2000 */ 00176 #define HTP_SERVER_IIS_5_1 6 /* Windows XP Professional */ 00177 #define HTP_SERVER_IIS_6_0 7 /* Windows 2003 */ 00178 #define HTP_SERVER_IIS_7_0 8 /* Windows 2008 */ 00179 #define HTP_SERVER_IIS_7_5 9 /* Windows 7 */ 00180 #define HTP_SERVER_TOMCAT_6_0 10 /* Unused */ 00181 #define HTP_SERVER_APACHE 11 00182 #define HTP_SERVER_APACHE_2_2 12 00183 00184 #define NONE 0 00185 #define IDENTITY 1 00186 #define CHUNKED 2 00187 00188 #define TX_PROGRESS_NEW 0 00189 #define TX_PROGRESS_REQ_LINE 1 00190 #define TX_PROGRESS_REQ_HEADERS 2 00191 #define TX_PROGRESS_REQ_BODY 3 00192 #define TX_PROGRESS_REQ_TRAILER 4 00193 #define TX_PROGRESS_WAIT 5 00194 #define TX_PROGRESS_RES_LINE 6 00195 #define TX_PROGRESS_RES_HEADERS 7 00196 #define TX_PROGRESS_RES_BODY 8 00197 #define TX_PROGRESS_RES_TRAILER 9 00198 #define TX_PROGRESS_DONE 10 00199 00200 #define STREAM_STATE_NEW 0 00201 #define STREAM_STATE_OPEN 1 00202 #define STREAM_STATE_CLOSED 2 00203 #define STREAM_STATE_ERROR 3 00204 #define STREAM_STATE_TUNNEL 4 00205 #define STREAM_STATE_DATA_OTHER 5 00206 #define STREAM_STATE_DATA 9 00207 00208 #define URL_DECODER_PRESERVE_PERCENT 0 00209 #define URL_DECODER_REMOVE_PERCENT 1 00210 #define URL_DECODER_DECODE_INVALID 2 00211 #define URL_DECODER_STATUS_400 400 00212 00213 #define NONE 0 00214 #define NO 0 00215 #define BESTFIT 0 00216 #define YES 1 00217 #define TERMINATE 1 00218 #define STATUS_400 400 00219 #define STATUS_404 401 00220 00221 #define HTP_AUTH_NONE 0 00222 #define HTP_AUTH_BASIC 1 00223 #define HTP_AUTH_DIGEST 2 00224 #define HTP_AUTH_UNKNOWN 9 00225 00226 #define HTP_FILE_MULTIPART 1 00227 #define HTP_FILE_PUT 2 00228 00229 #define IN_TEST_NEXT_BYTE_OR_RETURN(X) \ 00230 if ((X)->in_current_offset >= (X)->in_current_len) { \ 00231 return HTP_DATA; \ 00232 } 00233 00234 #define IN_NEXT_BYTE(X) \ 00235 if ((X)->in_current_offset < (X)->in_current_len) { \ 00236 (X)->in_next_byte = (X)->in_current_data[(X)->in_current_offset]; \ 00237 (X)->in_current_offset++; \ 00238 (X)->in_stream_offset++; \ 00239 } else { \ 00240 (X)->in_next_byte = -1; \ 00241 } 00242 00243 #define IN_NEXT_BYTE_OR_RETURN(X) \ 00244 if ((X)->in_current_offset < (X)->in_current_len) { \ 00245 (X)->in_next_byte = (X)->in_current_data[(X)->in_current_offset]; \ 00246 (X)->in_current_offset++; \ 00247 (X)->in_stream_offset++; \ 00248 } else { \ 00249 return HTP_DATA; \ 00250 } 00251 00252 #define IN_COPY_BYTE_OR_RETURN(X) \ 00253 if ((X)->in_current_offset < (X)->in_current_len) { \ 00254 (X)->in_next_byte = (X)->in_current_data[(X)->in_current_offset]; \ 00255 (X)->in_current_offset++; \ 00256 (X)->in_stream_offset++; \ 00257 } else { \ 00258 return HTP_DATA; \ 00259 } \ 00260 \ 00261 if ((X)->in_line_len < (X)->in_line_size) { \ 00262 (X)->in_line[(X)->in_line_len] = (X)->in_next_byte; \ 00263 (X)->in_line_len++; \ 00264 if (((X)->in_line_len == HTP_HEADER_LIMIT_SOFT)&&(!((X)->in_tx->flags & HTP_FIELD_LONG))) { \ 00265 (X)->in_tx->flags |= HTP_FIELD_LONG; \ 00266 htp_log((X), HTP_LOG_MARK, HTP_LOG_ERROR, HTP_LINE_TOO_LONG_SOFT, "Request field over soft limit"); \ 00267 } \ 00268 } else { \ 00269 htp_log((X), HTP_LOG_MARK, HTP_LOG_ERROR, HTP_LINE_TOO_LONG_HARD, "Request field over hard limit"); \ 00270 return HTP_ERROR; \ 00271 } 00272 00273 #define OUT_TEST_NEXT_BYTE_OR_RETURN(X) \ 00274 if ((X)->out_current_offset >= (X)->out_current_len) { \ 00275 return HTP_DATA; \ 00276 } 00277 00278 #define OUT_NEXT_BYTE(X) \ 00279 if ((X)->out_current_offset < (X)->out_current_len) { \ 00280 (X)->out_next_byte = (X)->out_current_data[(X)->out_current_offset]; \ 00281 (X)->out_current_offset++; \ 00282 (X)->out_stream_offset++; \ 00283 } else { \ 00284 (X)->out_next_byte = -1; \ 00285 } 00286 00287 #define OUT_NEXT_BYTE_OR_RETURN(X) \ 00288 if ((X)->out_current_offset < (X)->out_current_len) { \ 00289 (X)->out_next_byte = (X)->out_current_data[(X)->out_current_offset]; \ 00290 (X)->out_current_offset++; \ 00291 (X)->out_stream_offset++; \ 00292 } else { \ 00293 return HTP_DATA; \ 00294 } 00295 00296 #define OUT_COPY_BYTE_OR_RETURN(X) \ 00297 if ((X)->out_current_offset < (X)->out_current_len) { \ 00298 (X)->out_next_byte = (X)->out_current_data[(X)->out_current_offset]; \ 00299 (X)->out_current_offset++; \ 00300 (X)->out_stream_offset++; \ 00301 } else { \ 00302 return HTP_DATA; \ 00303 } \ 00304 \ 00305 if ((X)->out_line_len < (X)->out_line_size) { \ 00306 (X)->out_line[(X)->out_line_len] = (X)->out_next_byte; \ 00307 (X)->out_line_len++; \ 00308 if (((X)->out_line_len == HTP_HEADER_LIMIT_SOFT)&&(!((X)->out_tx->flags & HTP_FIELD_LONG))) { \ 00309 (X)->out_tx->flags |= HTP_FIELD_LONG; \ 00310 htp_log((X), HTP_LOG_MARK, HTP_LOG_ERROR, HTP_LINE_TOO_LONG_SOFT, "Response field over soft limit"); \ 00311 } \ 00312 } else { \ 00313 htp_log((X), HTP_LOG_MARK, HTP_LOG_ERROR, HTP_LINE_TOO_LONG_HARD, "Response field over hard limit"); \ 00314 return HTP_ERROR; \ 00315 } 00316 00317 #ifdef __cplusplus 00318 extern "C" { 00319 #endif 00320 00321 typedef struct timeval htp_time_t; 00322 00323 // -- Data structures ----------------------------------------------------------------------------- 00324 00325 struct htp_cfg_t { 00331 size_t field_limit_hard; 00332 00336 size_t field_limit_soft; 00337 00341 int log_level; 00342 00346 int tx_auto_destroy; 00347 00351 int spersonality; 00352 00354 int (*parse_request_line)(htp_connp_t *connp); 00355 00357 int (*parse_response_line)(htp_connp_t *connp); 00358 00360 int (*process_request_header)(htp_connp_t *connp); 00361 00363 int (*process_response_header)(htp_connp_t *connp); 00364 00366 int (*parameter_processor)(table_t *params, bstr *name, bstr *value); 00367 00368 00369 // Path handling 00370 00372 int path_backslash_separators; 00373 00375 int path_case_insensitive; 00376 00378 int path_compress_separators; 00379 00384 int path_control_char_handling; 00385 00389 int path_convert_utf8; 00390 00392 int path_decode_separators; 00393 00395 int path_decode_u_encoding; 00396 00400 int path_invalid_encoding_handling; 00401 00403 int path_invalid_utf8_handling; 00404 00406 int path_nul_encoded_handling; 00407 00409 int path_nul_raw_handling; 00410 00412 unsigned char bestfit_replacement_char; 00413 00414 int params_decode_u_encoding; 00415 int params_invalid_encoding_handling; 00416 int params_nul_encoded_handling; 00417 int params_nul_raw_handling; 00418 00420 int path_unicode_mapping; 00421 00423 int path_utf8_overlong_handling; 00424 00426 unsigned char *bestfit_map; 00427 00429 int generate_request_uri_normalized; 00430 00432 int response_decompression_enabled; 00433 00434 char *request_encoding; 00435 00436 char *internal_encoding; 00437 00438 int parse_request_cookies; 00439 int parse_request_http_authentication; 00440 int extract_request_files; 00441 char *tmpdir; 00442 00443 // Hooks 00444 00448 htp_hook_t *hook_transaction_start; 00449 00451 htp_hook_t *hook_request_line; 00452 00454 htp_hook_t *hook_request_uri_normalize; 00455 00457 htp_hook_t *hook_request_headers; 00458 00465 htp_hook_t *hook_request_body_data; 00466 00467 htp_hook_t *hook_request_file_data; 00468 00472 htp_hook_t *hook_request_trailer; 00473 00475 htp_hook_t *hook_request; 00476 00478 htp_hook_t *hook_response_line; 00479 00481 htp_hook_t *hook_response_headers; 00482 00490 htp_hook_t *hook_response_body_data; 00491 00495 htp_hook_t *hook_response_trailer; 00496 00501 htp_hook_t *hook_response; 00502 00506 htp_hook_t *hook_log; 00507 00509 void *user_data; 00510 }; 00511 00512 struct htp_conn_t { 00514 htp_connp_t *connp; 00515 00517 char *remote_addr; 00518 00520 int remote_port; 00521 00523 char *local_addr; 00524 00526 int local_port; 00527 00532 list_t *transactions; 00533 00535 list_t *messages; 00536 00538 unsigned int flags; 00539 00541 htp_time_t open_timestamp; 00542 00544 htp_time_t close_timestamp; 00545 00547 size_t in_data_counter; 00548 00550 size_t out_data_counter; 00551 00553 size_t in_packet_counter; 00554 00556 size_t out_packet_counter; 00557 }; 00558 00559 struct htp_connp_t { 00560 // General fields 00561 00563 htp_cfg_t *cfg; 00564 00569 int is_cfg_private; 00570 00572 htp_conn_t *conn; 00573 00575 void *user_data; 00576 00581 htp_log_t *last_error; 00582 00583 // Request parser fields 00584 00586 unsigned int in_status; 00587 00589 unsigned int out_status; 00590 00591 unsigned int out_data_other_at_tx_end; 00592 00594 htp_time_t in_timestamp; 00595 00597 unsigned char *in_current_data; 00598 00600 int64_t in_current_len; 00601 00603 int64_t in_current_offset; 00604 00606 size_t in_chunk_count; 00607 00609 size_t in_chunk_request_index; 00610 00612 int64_t in_stream_offset; 00613 00615 int in_next_byte; 00616 00618 unsigned char *in_line; 00619 00621 size_t in_line_size; 00622 00624 size_t in_line_len; 00625 00627 htp_tx_t *in_tx; 00628 00630 htp_header_line_t *in_header_line; 00631 00636 int in_header_line_index; 00637 00639 int in_header_line_counter; 00640 00646 int64_t in_content_length; 00647 00652 int64_t in_body_data_left; 00653 00657 int in_chunked_length; 00658 00660 int (*in_state)(htp_connp_t *); 00661 00662 // Response parser fields 00663 00668 size_t out_next_tx_index; 00669 00671 htp_time_t out_timestamp; 00672 00674 unsigned char *out_current_data; 00675 00677 int64_t out_current_len; 00678 00680 int64_t out_current_offset; 00681 00683 int64_t out_stream_offset; 00684 00686 int out_next_byte; 00687 00689 unsigned char *out_line; 00690 00692 size_t out_line_size; 00693 00695 size_t out_line_len; 00696 00698 htp_tx_t *out_tx; 00699 00701 htp_header_line_t *out_header_line; 00702 00707 int out_header_line_index; 00708 00710 int out_header_line_counter; 00711 00716 int64_t out_content_length; 00717 00719 int64_t out_body_data_left; 00720 00724 int out_chunked_length; 00725 00727 int (*out_state)(htp_connp_t *); 00728 00730 htp_decompressor_t *out_decompressor; 00731 00732 htp_file_t *put_file; 00733 }; 00734 00735 struct htp_file_t { 00737 int source; 00738 00740 bstr *filename; 00741 00743 size_t len; 00744 00746 char *tmpname; 00747 00749 int fd; 00750 }; 00751 00752 struct htp_file_data_t { 00754 htp_tx_t *tx; 00755 00757 htp_file_t *file; 00758 00760 unsigned char *data; 00761 00763 size_t len; 00764 }; 00765 00766 struct htp_log_t { 00768 htp_connp_t *connp; 00769 00771 htp_tx_t *tx; 00772 00774 const char *msg; 00775 00777 int level; 00778 00780 int code; 00781 00783 const char *file; 00784 00786 unsigned int line; 00787 }; 00788 00789 struct htp_header_line_t { 00791 bstr *line; 00792 00794 size_t name_offset; 00795 00797 size_t name_len; 00798 00800 size_t value_offset; 00801 00803 size_t value_len; 00804 00806 unsigned int has_nulls; 00807 00809 int first_nul_offset; 00810 00812 unsigned int flags; 00813 00815 htp_header_t *header; 00816 }; 00817 00818 struct htp_header_t { 00820 bstr *name; 00821 00823 bstr *value; 00824 00826 unsigned int flags; 00827 }; 00828 00829 struct htp_tx_t { 00831 htp_connp_t *connp; 00832 00834 htp_conn_t *conn; 00835 00837 htp_cfg_t *cfg; 00838 00843 int is_cfg_shared; 00844 00846 void *user_data; 00847 00848 // Request 00849 unsigned int request_ignored_lines; 00850 00852 bstr *request_line; 00853 00855 bstr *request_line_raw; 00856 00858 int request_line_nul; 00859 00861 int request_line_nul_offset; 00862 00864 bstr *request_method; 00865 00867 int request_method_number; 00868 00870 bstr *request_uri; 00871 00877 bstr *request_uri_normalized; 00878 00880 bstr *request_protocol; 00881 00885 int request_protocol_number; 00886 00888 int protocol_is_simple; 00889 00895 htp_uri_t *parsed_uri; 00896 00903 htp_uri_t *parsed_uri_incomplete; 00904 00910 size_t request_message_len; 00911 00917 size_t request_entity_len; 00918 00926 size_t request_nonfiledata_len; 00927 00932 size_t request_filedata_len; 00933 00935 list_t *request_header_lines; 00936 00938 size_t request_header_lines_no_trailers; 00939 00941 table_t *request_headers; 00942 00946 bstr *request_headers_raw; 00947 00951 size_t request_headers_raw_lines; 00952 00954 bstr *request_headers_sep; 00955 00959 int request_transfer_coding; 00960 00962 int request_content_encoding; 00963 00968 bstr *request_content_type; 00969 00970 00974 htp_hook_t *hook_request_body_data; 00975 00979 htp_hook_t *hook_response_body_data; 00980 00984 htp_urlenp_t *request_urlenp_query; 00985 00989 htp_urlenp_t *request_urlenp_body; 00990 00995 htp_mpartp_t *request_mpartp; 00996 00998 table_t *request_params_query; 00999 int request_params_query_reused; 01000 01002 table_t *request_params_body; 01003 int request_params_body_reused; 01004 01006 table_t *request_cookies; 01007 01008 int request_auth_type; 01009 bstr *request_auth_username; 01010 bstr *request_auth_password; 01011 01012 // Response 01013 01015 unsigned int response_ignored_lines; 01016 01018 bstr *response_line; 01019 01021 bstr *response_line_raw; 01022 01024 bstr *response_protocol; 01025 01029 int response_protocol_number; 01030 01032 bstr *response_status; 01033 01035 int response_status_number; 01036 01040 int response_status_expected_number; 01041 01043 bstr *response_message; 01044 01046 int seen_100continue; 01047 01049 list_t *response_header_lines; 01050 01052 table_t *response_headers; 01053 01055 bstr *response_headers_sep; 01056 01062 size_t response_message_len; 01063 01069 size_t response_entity_len; 01070 01072 int response_transfer_coding; 01073 01075 int response_content_encoding; 01076 01077 // Common 01078 01082 unsigned int flags; 01083 01085 unsigned int progress; 01086 }; 01087 01089 struct htp_tx_data_t { 01091 htp_tx_t *tx; 01092 01094 unsigned char *data; 01095 01097 size_t len; 01098 }; 01099 01104 struct htp_uri_t { 01106 bstr *scheme; 01107 01109 bstr *username; 01110 01112 bstr *password; 01113 01115 bstr *hostname; 01116 01118 bstr *port; 01119 01121 int port_number; 01122 01124 bstr *path; 01125 01127 bstr *query; 01128 01130 bstr *fragment; 01131 }; 01132 01133 // -- Functions ----------------------------------------------------------------------------------- 01134 01135 const char *htp_get_version(void); 01136 01137 htp_cfg_t *htp_config_copy(htp_cfg_t *cfg); 01138 htp_cfg_t *htp_config_create(void); 01139 void htp_config_destroy(htp_cfg_t *cfg); 01140 01141 void htp_config_register_transaction_start(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)); 01142 void htp_config_register_request_line(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)); 01143 void htp_config_register_request_uri_normalize(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)); 01144 void htp_config_register_request_headers(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)); 01145 void htp_config_register_request_body_data(htp_cfg_t *cfg, int (*callback_fn)(htp_tx_data_t *)); 01146 void htp_config_register_request_file_data(htp_cfg_t *cfg, int (*callback_fn)(htp_file_data_t *)); 01147 void htp_config_register_request_trailer(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)); 01148 void htp_config_register_request(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)); 01149 01150 void htp_config_register_response_line(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)); 01151 void htp_config_register_response_headers(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)); 01152 void htp_config_register_response_body_data(htp_cfg_t *cfg, int (*callback_fn)(htp_tx_data_t *)); 01153 void htp_config_register_response_trailer(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)); 01154 void htp_config_register_response(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)); 01155 01156 void htp_config_register_log(htp_cfg_t *cfg, int (*callback_fn)(htp_log_t *)); 01157 01158 void htp_config_set_tx_auto_destroy(htp_cfg_t *cfg, int tx_auto_destroy); 01159 01160 int htp_config_set_server_personality(htp_cfg_t *cfg, int personality); 01161 void htp_config_set_response_decompression(htp_cfg_t *cfg, int enabled); 01162 01163 void htp_config_set_bestfit_map(htp_cfg_t *cfg, unsigned char *map); 01164 void htp_config_set_path_backslash_separators(htp_cfg_t *cfg, int backslash_separators); 01165 void htp_config_set_path_case_insensitive(htp_cfg_t *cfg, int path_case_insensitive); 01166 void htp_config_set_path_compress_separators(htp_cfg_t *cfg, int compress_separators); 01167 void htp_config_set_path_control_char_handling(htp_cfg_t *cfg, int control_char_handling); 01168 void htp_config_set_path_convert_utf8(htp_cfg_t *cfg, int convert_utf8); 01169 void htp_config_set_path_decode_separators(htp_cfg_t *cfg, int backslash_separators); 01170 void htp_config_set_path_decode_u_encoding(htp_cfg_t *cfg, int decode_u_encoding); 01171 void htp_config_set_path_invalid_encoding_handling(htp_cfg_t *cfg, int invalid_encoding_handling); 01172 void htp_config_set_path_invalid_utf8_handling(htp_cfg_t *cfg, int invalid_utf8_handling); 01173 void htp_config_set_path_nul_encoded_handling(htp_cfg_t *cfg, int nul_encoded_handling); 01174 void htp_config_set_path_nul_raw_handling(htp_cfg_t *cfg, int nul_raw_handling); 01175 void htp_config_set_path_replacement_char(htp_cfg_t *cfg, int replacement_char); 01176 void htp_config_set_path_unicode_mapping(htp_cfg_t *cfg, int unicode_mapping); 01177 void htp_config_set_path_utf8_overlong_handling(htp_cfg_t *cfg, int utf8_overlong_handling); 01178 01179 void htp_config_set_generate_request_uri_normalized(htp_cfg_t *cfg, int generate); 01180 01181 void htp_config_register_urlencoded_parser(htp_cfg_t *cfg); 01182 void htp_config_register_multipart_parser(htp_cfg_t *cfg); 01183 01184 01185 htp_connp_t *htp_connp_create(htp_cfg_t *cfg); 01186 htp_connp_t *htp_connp_create_copycfg(htp_cfg_t *cfg); 01187 void htp_connp_open(htp_connp_t *connp, const char *remote_addr, int remote_port, const char *local_addr, int local_port, htp_time_t *timestamp); 01188 void htp_connp_close(htp_connp_t *connp, htp_time_t *timestamp); 01189 void htp_connp_destroy(htp_connp_t *connp); 01190 void htp_connp_destroy_all(htp_connp_t *connp); 01191 01192 void htp_connp_set_user_data(htp_connp_t *connp, void *user_data); 01193 void *htp_connp_get_user_data(htp_connp_t *connp); 01194 01195 htp_conn_t *htp_conn_create(htp_connp_t *connp); 01196 void htp_conn_destroy(htp_conn_t *conn); 01197 int htp_conn_remove_tx(htp_conn_t *conn, htp_tx_t *tx); 01198 01199 int htp_connp_req_data(htp_connp_t *connp, htp_time_t *timestamp, unsigned char *data, size_t len); 01200 size_t htp_connp_req_data_consumed(htp_connp_t *connp); 01201 int htp_connp_res_data(htp_connp_t *connp, htp_time_t *timestamp, unsigned char *data, size_t len); 01202 size_t htp_connp_res_data_consumed(htp_connp_t *connp); 01203 01204 void htp_connp_clear_error(htp_connp_t *connp); 01205 htp_log_t *htp_connp_get_last_error(htp_connp_t *connp); 01206 01207 htp_header_t *htp_connp_header_parse(htp_connp_t *, unsigned char *, size_t); 01208 01209 #define CFG_NOT_SHARED 0 01210 #define CFG_SHARED 1 01211 01212 htp_tx_t *htp_tx_create(htp_cfg_t *cfg, int is_cfg_shared, htp_conn_t *conn); 01213 void htp_tx_destroy(htp_tx_t *tx); 01214 void htp_tx_set_config(htp_tx_t *tx, htp_cfg_t *cfg, int is_cfg_shared); 01215 01216 void htp_tx_set_user_data(htp_tx_t *tx, void *user_data); 01217 void *htp_tx_get_user_data(htp_tx_t *tx); 01218 01219 // void htp_tx_register_response_body_data(htp_tx_t *tx, int (*callback_fn)(htp_tx_data_t *)); 01220 01221 // Parsing functions 01222 01223 int htp_parse_request_line_generic(htp_connp_t *connp); 01224 int htp_parse_request_header_generic(htp_connp_t *connp, htp_header_t *h, unsigned char *data, size_t len); 01225 int htp_process_request_header_generic(htp_connp_t *); 01226 01227 int htp_parse_request_header_apache_2_2(htp_connp_t *connp, htp_header_t *h, unsigned char *data, size_t len); 01228 int htp_parse_request_line_apache_2_2(htp_connp_t *connp); 01229 int htp_process_request_header_apache_2_2(htp_connp_t *); 01230 01231 int htp_parse_response_line_generic(htp_connp_t *connp); 01232 int htp_parse_response_header_generic(htp_connp_t *connp, htp_header_t *h, char *data, size_t len); 01233 int htp_process_response_header_generic(htp_connp_t *connp); 01234 01235 // Parser states 01236 01237 int htp_connp_REQ_IDLE(htp_connp_t *connp); 01238 int htp_connp_REQ_LINE(htp_connp_t *connp); 01239 int htp_connp_REQ_PROTOCOL(htp_connp_t *connp); 01240 int htp_connp_REQ_HEADERS(htp_connp_t *connp); 01241 int htp_connp_REQ_BODY_DETERMINE(htp_connp_t *connp); 01242 int htp_connp_REQ_BODY_IDENTITY(htp_connp_t *connp); 01243 int htp_connp_REQ_BODY_CHUNKED_LENGTH(htp_connp_t *connp); 01244 int htp_connp_REQ_BODY_CHUNKED_DATA(htp_connp_t *connp); 01245 int htp_connp_REQ_BODY_CHUNKED_DATA_END(htp_connp_t *connp); 01246 01247 int htp_connp_REQ_CONNECT_CHECK(htp_connp_t *connp); 01248 int htp_connp_REQ_CONNECT_WAIT_RESPONSE(htp_connp_t *connp); 01249 01250 int htp_connp_RES_IDLE(htp_connp_t *connp); 01251 int htp_connp_RES_LINE(htp_connp_t *connp); 01252 int htp_connp_RES_HEADERS(htp_connp_t *connp); 01253 int htp_connp_RES_BODY_DETERMINE(htp_connp_t *connp); 01254 int htp_connp_RES_BODY_IDENTITY(htp_connp_t *connp); 01255 int htp_connp_RES_BODY_CHUNKED_LENGTH(htp_connp_t *connp); 01256 int htp_connp_RES_BODY_CHUNKED_DATA(htp_connp_t *connp); 01257 int htp_connp_RES_BODY_CHUNKED_DATA_END(htp_connp_t *connp); 01258 01259 // Utility functions 01260 01261 int htp_convert_method_to_number(bstr *); 01262 int htp_is_lws(int c); 01263 int htp_is_separator(int c); 01264 int htp_is_text(int c); 01265 int htp_is_token(int c); 01266 int htp_chomp(unsigned char *data, size_t *len); 01267 int htp_is_space(int c); 01268 01269 int htp_parse_protocol(bstr *protocol); 01270 01271 int htp_is_line_empty(unsigned char *data, size_t len); 01272 int htp_is_line_whitespace(unsigned char *data, size_t len); 01273 01274 int htp_connp_is_line_folded(unsigned char *data, size_t len); 01275 int htp_connp_is_line_terminator(htp_connp_t *connp, unsigned char *data, size_t len); 01276 int htp_connp_is_line_ignorable(htp_connp_t *connp, unsigned char *data, size_t len); 01277 01278 int htp_parse_uri(bstr *input, htp_uri_t **uri); 01279 int htp_parse_authority(htp_connp_t *connp, bstr *input, htp_uri_t **uri); 01280 int htp_normalize_parsed_uri(htp_connp_t *connp, htp_uri_t *parsed_uri_incomplete, htp_uri_t *parsed_uri); 01281 bstr *htp_normalize_hostname_inplace(bstr *input); 01282 void htp_replace_hostname(htp_connp_t *connp, htp_uri_t *parsed_uri, bstr *hostname); 01283 int htp_is_uri_unreserved(unsigned char c); 01284 01285 int htp_decode_path_inplace(htp_cfg_t *cfg, htp_tx_t *tx, bstr *path); 01286 01287 void htp_uriencoding_normalize_inplace(bstr *s); 01288 01289 int htp_prenormalize_uri_path_inplace(bstr *s, int *flags, int case_insensitive, int backslash, int decode_separators, int remove_consecutive); 01290 void htp_normalize_uri_path_inplace(bstr *s); 01291 01292 void htp_utf8_decode_path_inplace(htp_cfg_t *cfg, htp_tx_t *tx, bstr *path); 01293 void htp_utf8_validate_path(htp_tx_t *tx, bstr *path); 01294 01295 int htp_parse_content_length(bstr *b); 01296 int htp_parse_chunked_length(unsigned char *data, size_t len); 01297 int htp_parse_positive_integer_whitespace(unsigned char *data, size_t len, int base); 01298 int htp_parse_status(bstr *status); 01299 int htp_parse_authorization_digest(htp_connp_t *connp, htp_header_t *auth_header); 01300 int htp_parse_authorization_basic(htp_connp_t *connp, htp_header_t *auth_header); 01301 01302 void htp_log(htp_connp_t *connp, const char *file, int line, int level, int code, const char *fmt, ...); 01303 void htp_print_log(FILE *stream, htp_log_t *log); 01304 01305 void fprint_bstr(FILE *stream, const char *name, bstr *b); 01306 void fprint_raw_data(FILE *stream, const char *name, unsigned char *data, size_t len); 01307 void fprint_raw_data_ex(FILE *stream, const char *name, unsigned char *data, size_t offset, size_t len); 01308 01309 char *htp_connp_in_state_as_string(htp_connp_t *connp); 01310 char *htp_connp_out_state_as_string(htp_connp_t *connp); 01311 char *htp_tx_progress_as_string(htp_tx_t *tx); 01312 01313 bstr *htp_unparse_uri_noencode(htp_uri_t *uri); 01314 01315 int htp_resembles_response_line(htp_tx_t *tx); 01316 01317 bstr *htp_tx_generate_request_headers_raw(htp_tx_t *tx); 01318 bstr *htp_tx_get_request_headers_raw(htp_tx_t *tx); 01319 01320 int htp_req_run_hook_body_data(htp_connp_t *connp, htp_tx_data_t *d); 01321 int htp_res_run_hook_body_data(htp_connp_t *connp, htp_tx_data_t *d); 01322 01323 void htp_tx_register_request_body_data(htp_tx_t *tx, int (*callback_fn)(htp_tx_data_t *)); 01324 void htp_tx_register_response_body_data(htp_tx_t *tx, int (*callback_fn)(htp_tx_data_t *)); 01325 01326 int htp_ch_urlencoded_callback_request_body_data(htp_tx_data_t *d); 01327 int htp_ch_urlencoded_callback_request_headers(htp_connp_t *connp); 01328 int htp_ch_urlencoded_callback_request_line(htp_connp_t *connp); 01329 int htp_ch_multipart_callback_request_body_data(htp_tx_data_t *d); 01330 int htp_ch_multipart_callback_request_headers(htp_connp_t *connp); 01331 01332 int htp_php_parameter_processor(table_t *params, bstr *name, bstr *value); 01333 01334 int htp_transcode_params(htp_connp_t *connp, table_t **params, int destroy_old); 01335 int htp_transcode_bstr(iconv_t cd, bstr *input, bstr **output); 01336 01337 int htp_parse_single_cookie_v0(htp_connp_t *connp, char *data, size_t len); 01338 int htp_parse_cookies_v0(htp_connp_t *connp); 01339 int htp_parse_authorization(htp_connp_t *connp); 01340 01341 int htp_decode_urlencoded_inplace(htp_cfg_t *cfg, htp_tx_t *tx, bstr *input); 01342 01343 bstr *htp_extract_quoted_string_as_bstr(char *data, size_t len, size_t *endoffset); 01344 01345 int htp_mpart_part_process_headers(htp_mpart_part_t *part); 01346 int htp_mpartp_parse_header(htp_mpart_part_t *part, unsigned char *data, size_t len); 01347 int htp_mpart_part_handle_data(htp_mpart_part_t *part, unsigned char *data, size_t len, int is_line); 01348 int htp_mpartp_is_boundary_character(int c); 01349 01350 #ifdef __cplusplus 01351 } 01352 #endif 01353 01354 #endif /* _HTP_H */ 01355 01356