1 /*************************************************************************** 2 * Copyright (c) 2009-2010 Open Information Security Foundation 3 * Copyright (c) 2010-2013 Qualys, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * - Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 17 * - Neither the name of the Qualys, Inc. nor the names of its 18 * contributors may be used to endorse or promote products derived from 19 * this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 ***************************************************************************/ 33 34 /** 35 * @file 36 * @author Ivan Ristic <ivanr@webkreator.com> 37 */ 38 39 #ifndef _HTP_PRIVATE_H 40 #define _HTP_PRIVATE_H 41 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 #if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) 47 /* C99 requires that inttypes.h only exposes PRI* macros 48 * for C++ implementations if this is defined: */ 49 #define __STDC_FORMAT_MACROS 50 #endif 51 52 #include <ctype.h> 53 #include <errno.h> 54 #include <iconv.h> 55 #include <inttypes.h> 56 #include <stdarg.h> 57 #include <stdio.h> 58 #include <stdlib.h> 59 #include <unistd.h> 60 #include <sys/types.h> 61 #include <sys/stat.h> 62 #include <stdint.h> 63 64 #include "htp_config_auto_gen.h" 65 #include "htp.h" 66 #include "htp_config_private.h" 67 #include "htp_connection_parser_private.h" 68 #include "htp_connection_private.h" 69 #include "htp_list_private.h" 70 #include "htp_multipart_private.h" 71 #include "htp_table_private.h" 72 73 #ifndef CR 74 #define CR '\r' 75 #endif 76 77 #ifndef LF 78 #define LF '\n' 79 #endif 80 81 // 1048576 is 1 Mbyte 82 #define HTP_LZMA_MEMLIMIT 1048576 83 //deflate max ratio is about 1000 84 #define HTP_COMPRESSION_BOMB_RATIO 2048 85 #define HTP_COMPRESSION_BOMB_LIMIT 1048576 86 // 0.1 second 87 #define HTP_COMPRESSION_TIME_LIMIT_USEC 100000 88 // test time for compression every 256 callbacks 89 #define HTP_COMPRESSION_TIME_FREQ_TEST 256 90 91 #define HTP_FIELD_LIMIT_HARD 18000 92 #define HTP_FIELD_LIMIT_SOFT 9000 93 94 #define HTP_VALID_STATUS_MIN 100 95 #define HTP_VALID_STATUS_MAX 999 96 97 // Parser states, in the order in which they are 98 // used as a single transaction is processed. 99 100 htp_status_t htp_connp_REQ_IDLE(htp_connp_t *connp); 101 htp_status_t htp_connp_REQ_LINE(htp_connp_t *connp); 102 htp_status_t htp_connp_REQ_LINE_complete(htp_connp_t *connp); 103 htp_status_t htp_connp_REQ_PROTOCOL(htp_connp_t *connp); 104 htp_status_t htp_connp_REQ_HEADERS(htp_connp_t *connp); 105 htp_status_t htp_connp_REQ_CONNECT_CHECK(htp_connp_t *connp); 106 htp_status_t htp_connp_REQ_CONNECT_WAIT_RESPONSE(htp_connp_t *connp); 107 htp_status_t htp_connp_REQ_CONNECT_PROBE_DATA(htp_connp_t *connp); 108 htp_status_t htp_connp_REQ_BODY_DETERMINE(htp_connp_t *connp); 109 htp_status_t htp_connp_REQ_BODY_IDENTITY(htp_connp_t *connp); 110 htp_status_t htp_connp_REQ_BODY_CHUNKED_LENGTH(htp_connp_t *connp); 111 htp_status_t htp_connp_REQ_BODY_CHUNKED_DATA(htp_connp_t *connp); 112 htp_status_t htp_connp_REQ_BODY_CHUNKED_DATA_END(htp_connp_t *connp); 113 htp_status_t htp_connp_REQ_FINALIZE(htp_connp_t *connp); 114 htp_status_t htp_connp_REQ_IGNORE_DATA_AFTER_HTTP_0_9(htp_connp_t *connp); 115 116 htp_status_t htp_connp_RES_IDLE(htp_connp_t *connp); 117 htp_status_t htp_connp_RES_LINE(htp_connp_t *connp); 118 htp_status_t htp_connp_RES_HEADERS(htp_connp_t *connp); 119 htp_status_t htp_connp_RES_BODY_DETERMINE(htp_connp_t *connp); 120 htp_status_t htp_connp_RES_BODY_IDENTITY_CL_KNOWN(htp_connp_t *connp); 121 htp_status_t htp_connp_RES_BODY_IDENTITY_STREAM_CLOSE(htp_connp_t *connp); 122 htp_status_t htp_connp_RES_BODY_CHUNKED_LENGTH(htp_connp_t *connp); 123 htp_status_t htp_connp_RES_BODY_CHUNKED_DATA(htp_connp_t *connp); 124 htp_status_t htp_connp_RES_BODY_CHUNKED_DATA_END(htp_connp_t *connp); 125 htp_status_t htp_connp_RES_FINALIZE(htp_connp_t *connp); 126 127 // Parsing functions 128 129 htp_status_t htp_parse_request_line_generic(htp_connp_t *connp); 130 htp_status_t htp_parse_request_line_generic_ex(htp_connp_t *connp, int nul_terminates); 131 htp_status_t htp_parse_request_header_generic(htp_connp_t *connp, htp_header_t *h, unsigned char *data, size_t len); 132 htp_status_t htp_process_request_header_generic(htp_connp_t *, unsigned char *data, size_t len); 133 134 htp_status_t htp_parse_request_line_apache_2_2(htp_connp_t *connp); 135 htp_status_t htp_process_request_header_apache_2_2(htp_connp_t *, unsigned char *data, size_t len); 136 137 htp_status_t htp_parse_response_line_generic(htp_connp_t *connp); 138 htp_status_t htp_parse_response_header_generic(htp_connp_t *connp, htp_header_t *h, unsigned char *data, size_t len); 139 htp_status_t htp_process_response_header_generic(htp_connp_t *connp, unsigned char *data, size_t len); 140 141 142 // Private transaction functions 143 144 htp_status_t htp_tx_state_response_complete_ex(htp_tx_t *tx, int hybrid_mode); 145 146 147 // Utility functions 148 149 int htp_convert_method_to_number(bstr *); 150 int htp_is_lws(int c); 151 int htp_is_separator(int c); 152 int htp_is_text(int c); 153 int htp_is_token(int c); 154 int htp_chomp(unsigned char *data, size_t *len); 155 int htp_is_space(int c); 156 157 int htp_parse_protocol(bstr *protocol); 158 159 int htp_is_line_empty(unsigned char *data, size_t len); 160 int htp_is_line_whitespace(unsigned char *data, size_t len); 161 162 int htp_connp_is_line_folded(unsigned char *data, size_t len); 163 int htp_is_folding_char(int c); 164 int htp_connp_is_line_terminator(htp_connp_t *connp, unsigned char *data, size_t len, int next_no_lf); 165 int htp_connp_is_line_ignorable(htp_connp_t *connp, unsigned char *data, size_t len); 166 167 int htp_parse_uri(bstr *input, htp_uri_t **uri); 168 htp_status_t htp_parse_hostport(bstr *authority, bstr **hostname, bstr **port, int *port_number, int *invalid); 169 htp_status_t htp_parse_header_hostport(bstr *authority, bstr **hostname, bstr **port, int *port_number, uint64_t *flags); 170 int htp_validate_hostname(bstr *hostname); 171 int htp_parse_uri_hostport(htp_connp_t *connp, bstr *input, htp_uri_t *uri); 172 int htp_normalize_parsed_uri(htp_tx_t *tx, htp_uri_t *parsed_uri_incomplete, htp_uri_t *parsed_uri); 173 bstr *htp_normalize_hostname_inplace(bstr *input); 174 175 int htp_decode_path_inplace(htp_tx_t *tx, bstr *path); 176 177 int htp_prenormalize_uri_path_inplace(bstr *s, int *flags, int case_insensitive, int backslash, int decode_separators, int remove_consecutive); 178 void htp_normalize_uri_path_inplace(bstr *s); 179 180 void htp_utf8_decode_path_inplace(htp_cfg_t *cfg, htp_tx_t *tx, bstr *path); 181 void htp_utf8_validate_path(htp_tx_t *tx, bstr *path); 182 183 int64_t htp_parse_content_length(bstr *b, htp_connp_t *connp); 184 int64_t htp_parse_chunked_length(unsigned char *data, size_t len); 185 int64_t htp_parse_positive_integer_whitespace(unsigned char *data, size_t len, int base); 186 int htp_parse_status(bstr *status); 187 int htp_parse_authorization_digest(htp_connp_t *connp, htp_header_t *auth_header); 188 int htp_parse_authorization_basic(htp_connp_t *connp, htp_header_t *auth_header); 189 190 void htp_print_log(FILE *stream, htp_log_t *log); 191 192 void fprint_bstr(FILE *stream, const char *name, bstr *b); 193 void fprint_raw_data(FILE *stream, const char *name, const void *data, size_t len); 194 void fprint_raw_data_ex(FILE *stream, const char *name, const void *data, size_t offset, size_t len); 195 196 char *htp_connp_in_state_as_string(htp_connp_t *connp); 197 char *htp_connp_out_state_as_string(htp_connp_t *connp); 198 char *htp_tx_request_progress_as_string(htp_tx_t *tx); 199 char *htp_tx_response_progress_as_string(htp_tx_t *tx); 200 201 bstr *htp_unparse_uri_noencode(htp_uri_t *uri); 202 203 int htp_treat_response_line_as_body(const uint8_t *data, size_t len); 204 205 htp_status_t htp_req_run_hook_body_data(htp_connp_t *connp, htp_tx_data_t *d); 206 htp_status_t htp_res_run_hook_body_data(htp_connp_t *connp, htp_tx_data_t *d); 207 208 htp_status_t htp_ch_urlencoded_callback_request_body_data(htp_tx_data_t *d); 209 htp_status_t htp_ch_urlencoded_callback_request_headers(htp_tx_t *tx); 210 htp_status_t htp_ch_urlencoded_callback_request_line(htp_tx_t *tx); 211 htp_status_t htp_ch_multipart_callback_request_body_data(htp_tx_data_t *d); 212 htp_status_t htp_ch_multipart_callback_request_headers(htp_tx_t *tx); 213 214 htp_status_t htp_php_parameter_processor(htp_param_t *p); 215 216 int htp_transcode_params(htp_connp_t *connp, htp_table_t **params, int destroy_old); 217 int htp_transcode_bstr(iconv_t cd, bstr *input, bstr **output); 218 219 int htp_parse_single_cookie_v0(htp_connp_t *connp, unsigned char *data, size_t len); 220 int htp_parse_cookies_v0(htp_connp_t *connp); 221 int htp_parse_authorization(htp_connp_t *connp); 222 223 htp_status_t htp_extract_quoted_string_as_bstr(unsigned char *data, size_t len, bstr **out, size_t *endoffset); 224 225 htp_header_t *htp_connp_header_parse(htp_connp_t *, unsigned char *, size_t); 226 227 htp_status_t htp_parse_ct_header(bstr *header, bstr **ct); 228 229 htp_status_t htp_connp_req_receiver_finalize_clear(htp_connp_t *connp); 230 htp_status_t htp_connp_res_receiver_finalize_clear(htp_connp_t *connp); 231 232 htp_status_t htp_tx_finalize(htp_tx_t *tx); 233 234 int htp_tx_is_complete(htp_tx_t *tx); 235 236 htp_status_t htp_tx_state_request_complete_partial(htp_tx_t *tx); 237 238 void htp_connp_tx_remove(htp_connp_t *connp, htp_tx_t *tx); 239 240 void htp_tx_destroy_incomplete(htp_tx_t *tx); 241 242 htp_status_t htp_tx_req_process_body_data_ex(htp_tx_t *tx, const void *data, size_t len); 243 htp_status_t htp_tx_res_process_body_data_ex(htp_tx_t *tx, const void *data, size_t len); 244 245 htp_status_t htp_tx_urldecode_uri_inplace(htp_tx_t *tx, bstr *input); 246 htp_status_t htp_tx_urldecode_params_inplace(htp_tx_t *tx, bstr *input); 247 248 void htp_connp_destroy_decompressors(htp_connp_t *connp); 249 250 #ifndef HAVE_STRLCAT 251 size_t strlcat(char *dst, const char *src, size_t size); 252 #endif 253 254 #ifndef HAVE_STRLCPY 255 size_t strlcpy(char *dst, const char *src, size_t size); 256 #endif 257 258 #ifdef __cplusplus 259 } 260 #endif 261 262 #endif /* _HTP_PRIVATE_H */ 263 264