HTP
0.5
|
#include <ctype.h>
#include <errno.h>
#include <iconv.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "htp.h"
#include "htp_config_private.h"
#include "htp_connection_parser_private.h"
#include "htp_connection_private.h"
#include "htp_list_private.h"
#include "htp_multipart_private.h"
#include "htp_table_private.h"
Go to the source code of this file.
Macros | |
#define | CR '\r' |
#define | LF '\n' |
#define | HTP_FIELD_LIMIT_HARD 18000 |
#define | HTP_FIELD_LIMIT_SOFT 9000 |
#define | HTP_VALID_STATUS_MIN 100 |
#define | HTP_VALID_STATUS_MAX 999 |
#define CR '\r' |
#define HTP_FIELD_LIMIT_HARD 18000 |
#define HTP_FIELD_LIMIT_SOFT 9000 |
#define HTP_VALID_STATUS_MAX 999 |
#define HTP_VALID_STATUS_MIN 100 |
#define LF '\n' |
void fprint_bstr | ( | FILE * | stream, |
const char * | name, | ||
bstr * | b | ||
) |
void fprint_raw_data | ( | FILE * | stream, |
const char * | name, | ||
const void * | data, | ||
size_t | len | ||
) |
void fprint_raw_data_ex | ( | FILE * | stream, |
const char * | name, | ||
const void * | data, | ||
size_t | offset, | ||
size_t | len | ||
) |
htp_status_t htp_ch_multipart_callback_request_body_data | ( | htp_tx_data_t * | d | ) |
Finalize Multipart processing.
[in] | d |
htp_status_t htp_ch_multipart_callback_request_headers | ( | htp_tx_t * | tx | ) |
Inspect request headers and register the Multipart request data hook if it contains a multipart/form-data body.
[in] | connp |
htp_status_t htp_ch_urlencoded_callback_request_body_data | ( | htp_tx_data_t * | d | ) |
This callback function feeds request body data to a Urlencoded parser and, later, feeds the parsed parameters to the correct structures.
[in] | d |
htp_status_t htp_ch_urlencoded_callback_request_headers | ( | htp_tx_t * | tx | ) |
Determine if the request has a Urlencoded body, and, if it does, create and attach an instance of the Urlencoded parser to the transaction.
[in] | connp |
htp_status_t htp_ch_urlencoded_callback_request_line | ( | htp_tx_t * | tx | ) |
Parses request query string, if present.
[in] | connp | |
[in] | raw_data | |
[in] | raw_len |
int htp_chomp | ( | unsigned char * | data, |
size_t * | len | ||
) |
Remove all line terminators (LF or CRLF) from the end of the line provided as input.
void htp_connp_destroy_decompressors | ( | htp_connp_t * | connp | ) |
htp_header_t* htp_connp_header_parse | ( | htp_connp_t * | , |
unsigned char * | , | ||
size_t | |||
) |
char* htp_connp_in_state_as_string | ( | htp_connp_t * | connp | ) |
int htp_connp_is_line_folded | ( | unsigned char * | data, |
size_t | len | ||
) |
Determines if the given line is a continuation (of some previous line).
[in] | data | |
[in] | len |
int htp_connp_is_line_ignorable | ( | htp_connp_t * | connp, |
unsigned char * | data, | ||
size_t | len | ||
) |
Determines if the given line can be ignored when it appears before a request.
[in] | connp | |
[in] | data | |
[in] | len |
int htp_connp_is_line_terminator | ( | htp_connp_t * | connp, |
unsigned char * | data, | ||
size_t | len | ||
) |
Determines if the given line is a request terminator.
[in] | connp | |
[in] | data | |
[in] | len |
char* htp_connp_out_state_as_string | ( | htp_connp_t * | connp | ) |
htp_status_t htp_connp_REQ_BODY_CHUNKED_DATA | ( | htp_connp_t * | connp | ) |
Processes a chunk of data.
[in] | connp |
htp_status_t htp_connp_REQ_BODY_CHUNKED_DATA_END | ( | htp_connp_t * | connp | ) |
Consumes bytes until the end of the current line.
[in] | connp |
htp_status_t htp_connp_REQ_BODY_CHUNKED_LENGTH | ( | htp_connp_t * | connp | ) |
Extracts chunk length.
[in] | connp |
htp_status_t htp_connp_REQ_BODY_DETERMINE | ( | htp_connp_t * | connp | ) |
Determines presence (and encoding) of a request body.
[in] | connp |
htp_status_t htp_connp_REQ_BODY_IDENTITY | ( | htp_connp_t * | connp | ) |
Processes identity request body.
[in] | connp |
htp_status_t htp_connp_REQ_CONNECT_CHECK | ( | htp_connp_t * | connp | ) |
Performs a check for a CONNECT transaction to decide whether inbound parsing needs to be suspended.
[in] | connp |
htp_status_t htp_connp_REQ_CONNECT_PROBE_DATA | ( | htp_connp_t * | connp | ) |
Determines whether inbound parsing needs to continue or stop. In case the data appears to be plain text HTTP, we try to continue.
[in] | connp |
htp_status_t htp_connp_REQ_CONNECT_WAIT_RESPONSE | ( | htp_connp_t * | connp | ) |
Determines whether inbound parsing, which was suspended after encountering a CONNECT transaction, can proceed (after receiving the response).
[in] | connp |
htp_status_t htp_connp_REQ_FINALIZE | ( | htp_connp_t * | connp | ) |
htp_status_t htp_connp_REQ_HEADERS | ( | htp_connp_t * | connp | ) |
Parses request headers.
[in] | connp |
htp_status_t htp_connp_REQ_IDLE | ( | htp_connp_t * | connp | ) |
The idle state is where the parser will end up after a transaction is processed. If there is more data available, a new request will be started.
[in] | connp |
htp_status_t htp_connp_REQ_IGNORE_DATA_AFTER_HTTP_0_9 | ( | htp_connp_t * | connp | ) |
htp_status_t htp_connp_REQ_LINE | ( | htp_connp_t * | connp | ) |
Parses request line.
[in] | connp |
htp_status_t htp_connp_REQ_LINE_complete | ( | htp_connp_t * | connp | ) |
Parse the request line.
[in] | connp |
htp_status_t htp_connp_REQ_PROTOCOL | ( | htp_connp_t * | connp | ) |
Determines request protocol.
[in] | connp |
htp_status_t htp_connp_req_receiver_finalize_clear | ( | htp_connp_t * | connp | ) |
Finalizes an existing data receiver hook by sending any outstanding data to it. The hook is then removed so that it receives no more data.
[in] | connp |
htp_status_t htp_connp_RES_BODY_CHUNKED_DATA | ( | htp_connp_t * | connp | ) |
Processes a chunk of data.
[in] | connp |
htp_status_t htp_connp_RES_BODY_CHUNKED_DATA_END | ( | htp_connp_t * | connp | ) |
Consumes bytes until the end of the current line.
[in] | connp |
htp_status_t htp_connp_RES_BODY_CHUNKED_LENGTH | ( | htp_connp_t * | connp | ) |
Extracts chunk length.
[in] | connp |
htp_status_t htp_connp_RES_BODY_DETERMINE | ( | htp_connp_t * | connp | ) |
Determines presence (and encoding) of a response body.
[in] | connp |
htp_status_t htp_connp_RES_BODY_IDENTITY_CL_KNOWN | ( | htp_connp_t * | connp | ) |
Processes an identity response body of known length.
[in] | connp |
htp_status_t htp_connp_RES_BODY_IDENTITY_STREAM_CLOSE | ( | htp_connp_t * | connp | ) |
Processes identity response body of unknown length. In this case, we assume the response body consumes all data until the end of the stream.
[in] | connp |
htp_status_t htp_connp_RES_FINALIZE | ( | htp_connp_t * | connp | ) |
htp_status_t htp_connp_RES_HEADERS | ( | htp_connp_t * | connp | ) |
Parses response headers.
[in] | connp |
htp_status_t htp_connp_RES_IDLE | ( | htp_connp_t * | connp | ) |
The response idle state will initialize response processing, as well as finalize each transactions after we are done with it.
[in] | connp |
htp_status_t htp_connp_RES_LINE | ( | htp_connp_t * | connp | ) |
Parses response line.
[in] | connp |
htp_status_t htp_connp_res_receiver_finalize_clear | ( | htp_connp_t * | connp | ) |
Finalizes an existing data receiver hook by sending any outstanding data to it. The hook is then removed so that it receives no more data.
[in] | connp |
void htp_connp_tx_remove | ( | htp_connp_t * | connp, |
htp_tx_t * | tx | ||
) |
Removes references to the supplied transaction.
[in] | connp | |
[in] | tx |
int htp_convert_method_to_number | ( | bstr * | method | ) |
Converts request method, given as a string, into a number.
[in] | method |
Decode a request path according to the settings in the provided configuration structure.
[in] | cfg | |
[in] | tx | |
[in] | path |
htp_status_t htp_extract_quoted_string_as_bstr | ( | unsigned char * | data, |
size_t | len, | ||
bstr ** | out, | ||
size_t * | endoffset | ||
) |
Parses the provided memory region, extracting the double-quoted string.
[in] | data | |
[in] | len | |
[out] | out | |
[out] | endoffset |
int htp_is_folding_char | ( | int | c | ) |
int htp_is_line_empty | ( | unsigned char * | data, |
size_t | len | ||
) |
Is the given line empty? This function expects the line to have a terminating LF.
[in] | data | |
[in] | len |
int htp_is_line_whitespace | ( | unsigned char * | data, |
size_t | len | ||
) |
Does line consist entirely of whitespace characters?
[in] | data | |
[in] | len |
int htp_is_lws | ( | int | c | ) |
Is character a linear white space character?
[in] | c |
int htp_is_separator | ( | int | c | ) |
Is character a separator character?
[in] | c |
int htp_is_space | ( | int | c | ) |
Is character a white space character?
[in] | c |
int htp_is_text | ( | int | c | ) |
Is character a text character?
[in] | c |
int htp_is_token | ( | int | c | ) |
Is character a token character?
[in] | c |
int htp_is_uri_unreserved | ( | unsigned char | c | ) |
Normalize request hostname. Convert all characters to lowercase and remove trailing dots from the end, if present.
[in] | hostname |
Normalize a previously-parsed request URI.
[in] | connp | |
[in] | incomplete | |
[in] | normalized |
void htp_normalize_uri_path_inplace | ( | bstr * | s | ) |
Normalize URL path. This function implements the remove dot segments algorithm specified in RFC 3986, section 5.2.4.
[in] | s |
int htp_parse_authorization | ( | htp_connp_t * | connp | ) |
Parses Authorization request header.
[in] | connp |
int htp_parse_authorization_basic | ( | htp_connp_t * | connp, |
htp_header_t * | auth_header | ||
) |
Parses Basic Authorization request header.
[in] | connp | |
[in] | auth_header |
int htp_parse_authorization_digest | ( | htp_connp_t * | connp, |
htp_header_t * | auth_header | ||
) |
Parses Digest Authorization request header.
[in] | connp | |
[in] | auth_header |
int64_t htp_parse_chunked_length | ( | unsigned char * | data, |
size_t | len | ||
) |
Parses chunk length (positive hexadecimal number). White space is allowed before and after the number. An error will be returned if the chunk length is greater than INT32_MAX.
[in] | data | |
[in] | len |
int64_t htp_parse_content_length | ( | bstr * | b | ) |
Parses Content-Length string (positive decimal number). White space is allowed before and after the number.
[in] | b |
int htp_parse_cookies_v0 | ( | htp_connp_t * | connp | ) |
Parses the Cookie request header in v0 format.
[in] | connp |
htp_status_t htp_parse_ct_header | ( | bstr * | header, |
bstr ** | ct | ||
) |
htp_status_t htp_parse_header_hostport | ( | bstr * | hostport, |
bstr ** | hostname, | ||
bstr ** | port, | ||
int * | port_number, | ||
uint64_t * | flags | ||
) |
Parses hostport provided in the Host header.
[in] | hostport | |
[out] | hostname | |
[out] | port | |
[out] | port_number | |
[out] | flags |
htp_status_t htp_parse_hostport | ( | bstr * | hostport, |
bstr ** | hostname, | ||
bstr ** | port, | ||
int * | port_number, | ||
int * | invalid | ||
) |
Parses an authority string, which consists of a hostname with an optional port number; username and password are not allowed and will not be handled.
[in] | hostport | |
[out] | hostname | A bstring containing the hostname, or NULL if the hostname is invalid. If this value is not NULL, the caller assumes responsibility for memory management. |
[out] | port | Port as text, or NULL if not provided. |
[out] | port_number | Port number, or -1 if the port is not present or invalid. |
[out] | invalid | Set to 1 if any part of the authority is invalid. |
int64_t htp_parse_positive_integer_whitespace | ( | unsigned char * | data, |
size_t | len, | ||
int | base | ||
) |
A somewhat forgiving parser for a positive integer in a given base. Only LWS is allowed before and after the number.
[in] | data | |
[in] | len | |
[in] | base |
int htp_parse_protocol | ( | bstr * | protocol | ) |
Determines protocol number from a textual representation (i.e., "HTTP/1.1"). This function will only understand a properly formatted protocol information. It does not try to be flexible.
[in] | protocol |
htp_status_t htp_parse_request_header_generic | ( | htp_connp_t * | connp, |
htp_header_t * | h, | ||
unsigned char * | data, | ||
size_t | len | ||
) |
Generic request header parser.
[in] | connp | |
[in] | h | |
[in] | data | |
[in] | len |
htp_status_t htp_parse_request_line_apache_2_2 | ( | htp_connp_t * | connp | ) |
Parse request line as Apache 2.2 does.
[in] | connp |
htp_status_t htp_parse_request_line_generic | ( | htp_connp_t * | connp | ) |
Generic request line parser.
[in] | connp |
htp_status_t htp_parse_request_line_generic_ex | ( | htp_connp_t * | connp, |
int | nul_terminates | ||
) |
htp_status_t htp_parse_response_header_generic | ( | htp_connp_t * | connp, |
htp_header_t * | h, | ||
unsigned char * | data, | ||
size_t | len | ||
) |
Generic response header parser.
[in] | connp | |
[in] | h | |
[in] | data | |
[in] | len |
htp_status_t htp_parse_response_line_generic | ( | htp_connp_t * | connp | ) |
Generic response line parser.
[in] | connp |
int htp_parse_single_cookie_v0 | ( | htp_connp_t * | connp, |
unsigned char * | data, | ||
size_t | len | ||
) |
Parses a single v0 request cookie and places the results into tx->request_cookies.
[in] | connp | |
[in] | data | |
[in] | len |
int htp_parse_status | ( | bstr * | status | ) |
Determines the numerical value of a response status given as a string.
[in] | status |
Parses request URI, making no attempt to validate the contents.
[in] | input | |
[in] | uri |
int htp_parse_uri_hostport | ( | htp_connp_t * | connp, |
bstr * | hostport, | ||
htp_uri_t * | uri | ||
) |
Parses hostport provided in the URI.
[in] | connp | |
[in] | hostport | |
[in] | uri |
htp_status_t htp_php_parameter_processor | ( | htp_param_t * | p | ) |
This is a proof-of-concept processor that processes parameter names in a way similar to PHP. Whitespace at the beginning is removed, and the remaining whitespace characters are converted to underscores. Proper research of PHP's behavior is needed before we can claim to be emulating it.
[in,out] | p |
int htp_prenormalize_uri_path_inplace | ( | bstr * | s, |
int * | flags, | ||
int | case_insensitive, | ||
int | backslash, | ||
int | decode_separators, | ||
int | remove_consecutive | ||
) |
void htp_print_log | ( | FILE * | stream, |
htp_log_t * | log | ||
) |
htp_status_t htp_process_request_header_apache_2_2 | ( | htp_connp_t * | connp, |
unsigned char * | data, | ||
size_t | len | ||
) |
Extract one request header. A header can span multiple lines, in which case they will be folded into one before parsing is attempted.
[in] | connp | |
[in] | data | |
[in] | len |
htp_status_t htp_process_request_header_generic | ( | htp_connp_t * | connp, |
unsigned char * | data, | ||
size_t | len | ||
) |
Extract one request header. A header can span multiple lines, in which case they will be folded into one before parsing is attempted.
[in] | connp | |
[in] | data | |
[in] | len |
htp_status_t htp_process_response_header_generic | ( | htp_connp_t * | connp, |
unsigned char * | data, | ||
size_t | len | ||
) |
Generic response header line(s) processor, which assembles folded lines into a single buffer before invoking the parsing function.
[in] | connp | |
[in] | data | |
[in] | len |
void htp_replace_hostname | ( | htp_connp_t * | connp, |
htp_uri_t * | parsed_uri, | ||
bstr * | hostname | ||
) |
htp_status_t htp_req_run_hook_body_data | ( | htp_connp_t * | connp, |
htp_tx_data_t * | d | ||
) |
Run the REQUEST_BODY_DATA hook.
[in] | connp | |
[in] | d |
htp_status_t htp_res_run_hook_body_data | ( | htp_connp_t * | connp, |
htp_tx_data_t * | d | ||
) |
Run the RESPONSE_BODY_DATA hook.
[in] | connp | |
[in] | d |
Transcode one bstr.
[in] | cd | |
[in] | input | |
[in] | output |
int htp_transcode_params | ( | htp_connp_t * | connp, |
htp_table_t ** | params, | ||
int | destroy_old | ||
) |
Transcode all parameters supplied in the table.
[in] | connp | |
[in] | params | |
[in] | destroy_old |
int htp_treat_response_line_as_body | ( | const uint8_t * | data, |
size_t | len | ||
) |
Determine if the information provided on the response line is good enough. Browsers are lax when it comes to response line parsing. In most cases they will only look for the words "http" at the beginning.
[in] | data | pointer to bytearray |
[in] | len | length in bytes of data |
void htp_tx_destroy_incomplete | ( | htp_tx_t * | tx | ) |
htp_status_t htp_tx_finalize | ( | htp_tx_t * | tx | ) |
int htp_tx_is_complete | ( | htp_tx_t * | tx | ) |
htp_status_t htp_tx_req_process_body_data_ex | ( | htp_tx_t * | tx, |
const void * | data, | ||
size_t | len | ||
) |
char* htp_tx_request_progress_as_string | ( | htp_tx_t * | tx | ) |
htp_status_t htp_tx_res_process_body_data_ex | ( | htp_tx_t * | tx, |
const void * | data, | ||
size_t | len | ||
) |
char* htp_tx_response_progress_as_string | ( | htp_tx_t * | tx | ) |
htp_status_t htp_tx_state_request_complete_partial | ( | htp_tx_t * | tx | ) |
htp_status_t htp_tx_state_response_complete_ex | ( | htp_tx_t * | tx, |
int | hybrid_mode | ||
) |
htp_status_t htp_tx_urldecode_params_inplace | ( | htp_tx_t * | tx, |
bstr * | input | ||
) |
htp_status_t htp_tx_urldecode_uri_inplace | ( | htp_tx_t * | tx, |
bstr * | input | ||
) |
Decode a UTF-8 encoded path. Overlong characters will be decoded, invalid characters will be left as-is. Best-fit mapping will be used to convert UTF-8 into a single-byte stream.
[in] | cfg | |
[in] | tx | |
[in] | path |
Validate a path that is quite possibly UTF-8 encoded.
[in] | tx | |
[in] | path |
int htp_validate_hostname | ( | bstr * | hostname | ) |
Implements relaxed (not strictly RFC) hostname validation.
[in] | hostname |
size_t strlcat | ( | char * | dst, |
const char * | src, | ||
size_t | size | ||
) |
size_t strlcpy | ( | char * | dst, |
const char * | src, | ||
size_t | size | ||
) |