mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
717 lines
27 KiB
C
717 lines
27 KiB
C
/*
|
|
* LibHTP (http://www.libhtp.org)
|
|
* Copyright 2009,2010 Ivan Ristic <ivanr@webkreator.com>
|
|
*
|
|
* LibHTP is an open source product, released under terms of the General Public Licence
|
|
* version 2 (GPLv2). Please refer to the file LICENSE, which contains the complete text
|
|
* of the license.
|
|
*
|
|
* In addition, there is a special exception that allows LibHTP to be freely
|
|
* used with any OSI-approved open source licence. Please refer to the file
|
|
* LIBHTP_LICENSING_EXCEPTION for the full text of the exception.
|
|
*
|
|
*/
|
|
|
|
#include "htp.h"
|
|
|
|
/**
|
|
* This map is used by default for best-fit mapping from the Unicode
|
|
* values U+0100-FFFF.
|
|
*/
|
|
static unsigned char bestfit_1252[] =
|
|
{ 0x01, 0x00, 0x41, 0x01, 0x01, 0x61, 0x01, 0x02, 0x41, 0x01, 0x03, 0x61,
|
|
0x01, 0x04, 0x41, 0x01, 0x05, 0x61, 0x01, 0x06, 0x43, 0x01, 0x07, 0x63,
|
|
0x01, 0x08, 0x43, 0x01, 0x09, 0x63, 0x01, 0x0a, 0x43, 0x01, 0x0b, 0x63,
|
|
0x01, 0x0c, 0x43, 0x01, 0x0d, 0x63, 0x01, 0x0e, 0x44, 0x01, 0x0f, 0x64,
|
|
0x01, 0x11, 0x64, 0x01, 0x12, 0x45, 0x01, 0x13, 0x65, 0x01, 0x14, 0x45,
|
|
0x01, 0x15, 0x65, 0x01, 0x16, 0x45, 0x01, 0x17, 0x65, 0x01, 0x18, 0x45,
|
|
0x01, 0x19, 0x65, 0x01, 0x1a, 0x45, 0x01, 0x1b, 0x65, 0x01, 0x1c, 0x47,
|
|
0x01, 0x1d, 0x67, 0x01, 0x1e, 0x47, 0x01, 0x1f, 0x67, 0x01, 0x20, 0x47,
|
|
0x01, 0x21, 0x67, 0x01, 0x22, 0x47, 0x01, 0x23, 0x67, 0x01, 0x24, 0x48,
|
|
0x01, 0x25, 0x68, 0x01, 0x26, 0x48, 0x01, 0x27, 0x68, 0x01, 0x28, 0x49,
|
|
0x01, 0x29, 0x69, 0x01, 0x2a, 0x49, 0x01, 0x2b, 0x69, 0x01, 0x2c, 0x49,
|
|
0x01, 0x2d, 0x69, 0x01, 0x2e, 0x49, 0x01, 0x2f, 0x69, 0x01, 0x30, 0x49,
|
|
0x01, 0x31, 0x69, 0x01, 0x34, 0x4a, 0x01, 0x35, 0x6a, 0x01, 0x36, 0x4b,
|
|
0x01, 0x37, 0x6b, 0x01, 0x39, 0x4c, 0x01, 0x3a, 0x6c, 0x01, 0x3b, 0x4c,
|
|
0x01, 0x3c, 0x6c, 0x01, 0x3d, 0x4c, 0x01, 0x3e, 0x6c, 0x01, 0x41, 0x4c,
|
|
0x01, 0x42, 0x6c, 0x01, 0x43, 0x4e, 0x01, 0x44, 0x6e, 0x01, 0x45, 0x4e,
|
|
0x01, 0x46, 0x6e, 0x01, 0x47, 0x4e, 0x01, 0x48, 0x6e, 0x01, 0x4c, 0x4f,
|
|
0x01, 0x4d, 0x6f, 0x01, 0x4e, 0x4f, 0x01, 0x4f, 0x6f, 0x01, 0x50, 0x4f,
|
|
0x01, 0x51, 0x6f, 0x01, 0x54, 0x52, 0x01, 0x55, 0x72, 0x01, 0x56, 0x52,
|
|
0x01, 0x57, 0x72, 0x01, 0x58, 0x52, 0x01, 0x59, 0x72, 0x01, 0x5a, 0x53,
|
|
0x01, 0x5b, 0x73, 0x01, 0x5c, 0x53, 0x01, 0x5d, 0x73, 0x01, 0x5e, 0x53,
|
|
0x01, 0x5f, 0x73, 0x01, 0x62, 0x54, 0x01, 0x63, 0x74, 0x01, 0x64, 0x54,
|
|
0x01, 0x65, 0x74, 0x01, 0x66, 0x54, 0x01, 0x67, 0x74, 0x01, 0x68, 0x55,
|
|
0x01, 0x69, 0x75, 0x01, 0x6a, 0x55, 0x01, 0x6b, 0x75, 0x01, 0x6c, 0x55,
|
|
0x01, 0x6d, 0x75, 0x01, 0x6e, 0x55, 0x01, 0x6f, 0x75, 0x01, 0x70, 0x55,
|
|
0x01, 0x71, 0x75, 0x01, 0x72, 0x55, 0x01, 0x73, 0x75, 0x01, 0x74, 0x57,
|
|
0x01, 0x75, 0x77, 0x01, 0x76, 0x59, 0x01, 0x77, 0x79, 0x01, 0x79, 0x5a,
|
|
0x01, 0x7b, 0x5a, 0x01, 0x7c, 0x7a, 0x01, 0x80, 0x62, 0x01, 0x97, 0x49,
|
|
0x01, 0x9a, 0x6c, 0x01, 0x9f, 0x4f, 0x01, 0xa0, 0x4f, 0x01, 0xa1, 0x6f,
|
|
0x01, 0xab, 0x74, 0x01, 0xae, 0x54, 0x01, 0xaf, 0x55, 0x01, 0xb0, 0x75,
|
|
0x01, 0xb6, 0x7a, 0x01, 0xc0, 0x7c, 0x01, 0xc3, 0x21, 0x01, 0xcd, 0x41,
|
|
0x01, 0xce, 0x61, 0x01, 0xcf, 0x49, 0x01, 0xd0, 0x69, 0x01, 0xd1, 0x4f,
|
|
0x01, 0xd2, 0x6f, 0x01, 0xd3, 0x55, 0x01, 0xd4, 0x75, 0x01, 0xd5, 0x55,
|
|
0x01, 0xd6, 0x75, 0x01, 0xd7, 0x55, 0x01, 0xd8, 0x75, 0x01, 0xd9, 0x55,
|
|
0x01, 0xda, 0x75, 0x01, 0xdb, 0x55, 0x01, 0xdc, 0x75, 0x01, 0xde, 0x41,
|
|
0x01, 0xdf, 0x61, 0x01, 0xe4, 0x47, 0x01, 0xe5, 0x67, 0x01, 0xe6, 0x47,
|
|
0x01, 0xe7, 0x67, 0x01, 0xe8, 0x4b, 0x01, 0xe9, 0x6b, 0x01, 0xea, 0x4f,
|
|
0x01, 0xeb, 0x6f, 0x01, 0xec, 0x4f, 0x01, 0xed, 0x6f, 0x01, 0xf0, 0x6a,
|
|
0x02, 0x61, 0x67, 0x02, 0xb9, 0x27, 0x02, 0xba, 0x22, 0x02, 0xbc, 0x27,
|
|
0x02, 0xc4, 0x5e, 0x02, 0xc8, 0x27, 0x02, 0xcb, 0x60, 0x02, 0xcd, 0x5f,
|
|
0x03, 0x00, 0x60, 0x03, 0x02, 0x5e, 0x03, 0x03, 0x7e, 0x03, 0x0e, 0x22,
|
|
0x03, 0x31, 0x5f, 0x03, 0x32, 0x5f, 0x03, 0x7e, 0x3b, 0x03, 0x93, 0x47,
|
|
0x03, 0x98, 0x54, 0x03, 0xa3, 0x53, 0x03, 0xa6, 0x46, 0x03, 0xa9, 0x4f,
|
|
0x03, 0xb1, 0x61, 0x03, 0xb4, 0x64, 0x03, 0xb5, 0x65, 0x03, 0xc0, 0x70,
|
|
0x03, 0xc3, 0x73, 0x03, 0xc4, 0x74, 0x03, 0xc6, 0x66, 0x04, 0xbb, 0x68,
|
|
0x05, 0x89, 0x3a, 0x06, 0x6a, 0x25, 0x20, 0x00, 0x20, 0x20, 0x01, 0x20,
|
|
0x20, 0x02, 0x20, 0x20, 0x03, 0x20, 0x20, 0x04, 0x20, 0x20, 0x05, 0x20,
|
|
0x20, 0x06, 0x20, 0x20, 0x10, 0x2d, 0x20, 0x11, 0x2d, 0x20, 0x17, 0x3d,
|
|
0x20, 0x32, 0x27, 0x20, 0x35, 0x60, 0x20, 0x44, 0x2f, 0x20, 0x74, 0x34,
|
|
0x20, 0x75, 0x35, 0x20, 0x76, 0x36, 0x20, 0x77, 0x37, 0x20, 0x78, 0x38,
|
|
0x20, 0x7f, 0x6e, 0x20, 0x80, 0x30, 0x20, 0x81, 0x31, 0x20, 0x82, 0x32,
|
|
0x20, 0x83, 0x33, 0x20, 0x84, 0x34, 0x20, 0x85, 0x35, 0x20, 0x86, 0x36,
|
|
0x20, 0x87, 0x37, 0x20, 0x88, 0x38, 0x20, 0x89, 0x39, 0x20, 0xa7, 0x50,
|
|
0x21, 0x02, 0x43, 0x21, 0x07, 0x45, 0x21, 0x0a, 0x67, 0x21, 0x0b, 0x48,
|
|
0x21, 0x0c, 0x48, 0x21, 0x0d, 0x48, 0x21, 0x0e, 0x68, 0x21, 0x10, 0x49,
|
|
0x21, 0x11, 0x49, 0x21, 0x12, 0x4c, 0x21, 0x13, 0x6c, 0x21, 0x15, 0x4e,
|
|
0x21, 0x18, 0x50, 0x21, 0x19, 0x50, 0x21, 0x1a, 0x51, 0x21, 0x1b, 0x52,
|
|
0x21, 0x1c, 0x52, 0x21, 0x1d, 0x52, 0x21, 0x24, 0x5a, 0x21, 0x28, 0x5a,
|
|
0x21, 0x2a, 0x4b, 0x21, 0x2c, 0x42, 0x21, 0x2d, 0x43, 0x21, 0x2e, 0x65,
|
|
0x21, 0x2f, 0x65, 0x21, 0x30, 0x45, 0x21, 0x31, 0x46, 0x21, 0x33, 0x4d,
|
|
0x21, 0x34, 0x6f, 0x22, 0x12, 0x2d, 0x22, 0x15, 0x2f, 0x22, 0x16, 0x5c,
|
|
0x22, 0x17, 0x2a, 0x22, 0x1a, 0x76, 0x22, 0x1e, 0x38, 0x22, 0x23, 0x7c,
|
|
0x22, 0x29, 0x6e, 0x22, 0x36, 0x3a, 0x22, 0x3c, 0x7e, 0x22, 0x61, 0x3d,
|
|
0x22, 0x64, 0x3d, 0x22, 0x65, 0x3d, 0x23, 0x03, 0x5e, 0x23, 0x20, 0x28,
|
|
0x23, 0x21, 0x29, 0x23, 0x29, 0x3c, 0x23, 0x2a, 0x3e, 0x25, 0x00, 0x2d,
|
|
0x25, 0x0c, 0x2b, 0x25, 0x10, 0x2b, 0x25, 0x14, 0x2b, 0x25, 0x18, 0x2b,
|
|
0x25, 0x1c, 0x2b, 0x25, 0x2c, 0x2d, 0x25, 0x34, 0x2d, 0x25, 0x3c, 0x2b,
|
|
0x25, 0x50, 0x2d, 0x25, 0x52, 0x2b, 0x25, 0x53, 0x2b, 0x25, 0x54, 0x2b,
|
|
0x25, 0x55, 0x2b, 0x25, 0x56, 0x2b, 0x25, 0x57, 0x2b, 0x25, 0x58, 0x2b,
|
|
0x25, 0x59, 0x2b, 0x25, 0x5a, 0x2b, 0x25, 0x5b, 0x2b, 0x25, 0x5c, 0x2b,
|
|
0x25, 0x5d, 0x2b, 0x25, 0x64, 0x2d, 0x25, 0x65, 0x2d, 0x25, 0x66, 0x2d,
|
|
0x25, 0x67, 0x2d, 0x25, 0x68, 0x2d, 0x25, 0x69, 0x2d, 0x25, 0x6a, 0x2b,
|
|
0x25, 0x6b, 0x2b, 0x25, 0x6c, 0x2b, 0x25, 0x84, 0x5f, 0x27, 0x58, 0x7c,
|
|
0x30, 0x00, 0x20, 0x30, 0x08, 0x3c, 0x30, 0x09, 0x3e, 0x30, 0x1a, 0x5b,
|
|
0x30, 0x1b, 0x5d, 0xff, 0x01, 0x21, 0xff, 0x02, 0x22, 0xff, 0x03, 0x23,
|
|
0xff, 0x04, 0x24, 0xff, 0x05, 0x25, 0xff, 0x06, 0x26, 0xff, 0x07, 0x27,
|
|
0xff, 0x08, 0x28, 0xff, 0x09, 0x29, 0xff, 0x0a, 0x2a, 0xff, 0x0b, 0x2b,
|
|
0xff, 0x0c, 0x2c, 0xff, 0x0d, 0x2d, 0xff, 0x0e, 0x2e, 0xff, 0x0f, 0x2f,
|
|
0xff, 0x10, 0x30, 0xff, 0x11, 0x31, 0xff, 0x12, 0x32, 0xff, 0x13, 0x33,
|
|
0xff, 0x14, 0x34, 0xff, 0x15, 0x35, 0xff, 0x16, 0x36, 0xff, 0x17, 0x37,
|
|
0xff, 0x18, 0x38, 0xff, 0x19, 0x39, 0xff, 0x1a, 0x3a, 0xff, 0x1b, 0x3b,
|
|
0xff, 0x1c, 0x3c, 0xff, 0x1d, 0x3d, 0xff, 0x1e, 0x3e, 0xff, 0x20, 0x40,
|
|
0xff, 0x21, 0x41, 0xff, 0x22, 0x42, 0xff, 0x23, 0x43, 0xff, 0x24, 0x44,
|
|
0xff, 0x25, 0x45, 0xff, 0x26, 0x46, 0xff, 0x27, 0x47, 0xff, 0x28, 0x48,
|
|
0xff, 0x29, 0x49, 0xff, 0x2a, 0x4a, 0xff, 0x2b, 0x4b, 0xff, 0x2c, 0x4c,
|
|
0xff, 0x2d, 0x4d, 0xff, 0x2e, 0x4e, 0xff, 0x2f, 0x4f, 0xff, 0x30, 0x50,
|
|
0xff, 0x31, 0x51, 0xff, 0x32, 0x52, 0xff, 0x33, 0x53, 0xff, 0x34, 0x54,
|
|
0xff, 0x35, 0x55, 0xff, 0x36, 0x56, 0xff, 0x37, 0x57, 0xff, 0x38, 0x58,
|
|
0xff, 0x39, 0x59, 0xff, 0x3a, 0x5a, 0xff, 0x3b, 0x5b, 0xff, 0x3c, 0x5c,
|
|
0xff, 0x3d, 0x5d, 0xff, 0x3e, 0x5e, 0xff, 0x3f, 0x5f, 0xff, 0x40, 0x60,
|
|
0xff, 0x41, 0x61, 0xff, 0x42, 0x62, 0xff, 0x43, 0x63, 0xff, 0x44, 0x64,
|
|
0xff, 0x45, 0x65, 0xff, 0x46, 0x66, 0xff, 0x47, 0x67, 0xff, 0x48, 0x68,
|
|
0xff, 0x49, 0x69, 0xff, 0x4a, 0x6a, 0xff, 0x4b, 0x6b, 0xff, 0x4c, 0x6c,
|
|
0xff, 0x4d, 0x6d, 0xff, 0x4e, 0x6e, 0xff, 0x4f, 0x6f, 0xff, 0x50, 0x70,
|
|
0xff, 0x51, 0x71, 0xff, 0x52, 0x72, 0xff, 0x53, 0x73, 0xff, 0x54, 0x74,
|
|
0xff, 0x55, 0x75, 0xff, 0x56, 0x76, 0xff, 0x57, 0x77, 0xff, 0x58, 0x78,
|
|
0xff, 0x59, 0x79, 0xff, 0x5a, 0x7a, 0xff, 0x5b, 0x7b, 0xff, 0x5c, 0x7c,
|
|
0xff, 0x5d, 0x7d, 0xff, 0x5e, 0x7e, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
/**
|
|
* Creates a new configuration structure. Configuration structures created at
|
|
* configuration time must not be changed afterwards in order to support lock-less
|
|
* copying.
|
|
*
|
|
* @return New configuration structure.
|
|
*/
|
|
htp_cfg_t *htp_config_create() {
|
|
htp_cfg_t *cfg = calloc(1, sizeof(htp_cfg_t));
|
|
if (cfg == NULL) return NULL;
|
|
|
|
cfg->field_limit_hard = HTP_HEADER_LIMIT_HARD;
|
|
cfg->field_limit_soft = HTP_HEADER_LIMIT_SOFT;
|
|
cfg->log_level = HTP_LOG_NOTICE;
|
|
|
|
cfg->path_u_bestfit_map = bestfit_1252;
|
|
cfg->path_replacement_char = '?';
|
|
|
|
// No need to create hooks here; they will be created on-demand,
|
|
// during callback registration
|
|
|
|
// Set the default personality before we return
|
|
htp_config_set_server_personality(cfg, HTP_SERVER_MINIMAL);
|
|
|
|
return cfg;
|
|
}
|
|
|
|
/**
|
|
* Creates a copy of the supplied configuration structure. The idea is to create
|
|
* one or more configuration objects at configuration-time, but to use this
|
|
* function to create per-connection copies. That way it will be possible to
|
|
* adjust per-connection configuration as necessary, without affecting the
|
|
* global configuration. Make sure no other thread changes the configuration
|
|
* object while this function is operating.
|
|
*
|
|
* @param cfg
|
|
* @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));
|
|
if (copy == NULL) return NULL;
|
|
|
|
// Create copies of the hooks' structures
|
|
if (cfg->hook_transaction_start != NULL) {
|
|
copy->hook_transaction_start = hook_copy(cfg->hook_transaction_start);
|
|
if (copy->hook_transaction_start == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_request_line != NULL) {
|
|
copy->hook_request_line = hook_copy(cfg->hook_request_line);
|
|
if (copy->hook_request_line == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_request_headers != NULL) {
|
|
copy->hook_request_headers = hook_copy(cfg->hook_request_headers);
|
|
if (copy->hook_request_headers == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_request_body_data != NULL) {
|
|
copy->hook_request_body_data = hook_copy(cfg->hook_request_body_data);
|
|
if (copy->hook_request_body_data == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_request_trailer != NULL) {
|
|
copy->hook_request_trailer = hook_copy(cfg->hook_request_trailer);
|
|
if (copy->hook_request_trailer == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_request != NULL) {
|
|
copy->hook_request = hook_copy(cfg->hook_request);
|
|
if (copy->hook_request == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_response_line != NULL) {
|
|
copy->hook_response_line = hook_copy(cfg->hook_response_line);
|
|
if (copy->hook_response_line == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_response_headers != NULL) {
|
|
copy->hook_response_headers = hook_copy(cfg->hook_response_headers);
|
|
if (copy->hook_response_headers == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_response_body_data != NULL) {
|
|
copy->hook_response_body_data = hook_copy(cfg->hook_response_body_data);
|
|
if (copy->hook_response_body_data == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_response_trailer != NULL) {
|
|
copy->hook_response_trailer = hook_copy(cfg->hook_response_trailer);
|
|
if (copy->hook_response_trailer == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_response != NULL) {
|
|
copy->hook_response = hook_copy(cfg->hook_response);
|
|
if (copy->hook_response == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (cfg->hook_log != NULL) {
|
|
copy->hook_log = hook_copy(cfg->hook_log);
|
|
if (copy->hook_log == NULL) {
|
|
free(copy);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return copy;
|
|
}
|
|
|
|
/**
|
|
* Destroy a configuration structure.
|
|
*
|
|
* @param cfg
|
|
*/
|
|
void htp_config_destroy(htp_cfg_t *cfg) {
|
|
// Destroy the hooks
|
|
hook_destroy(cfg->hook_transaction_start);
|
|
hook_destroy(cfg->hook_request_line);
|
|
hook_destroy(cfg->hook_request_headers);
|
|
hook_destroy(cfg->hook_request_body_data);
|
|
hook_destroy(cfg->hook_request_trailer);
|
|
hook_destroy(cfg->hook_request);
|
|
hook_destroy(cfg->hook_response_line);
|
|
hook_destroy(cfg->hook_response_headers);
|
|
hook_destroy(cfg->hook_response_body_data);
|
|
hook_destroy(cfg->hook_response_trailer);
|
|
hook_destroy(cfg->hook_response);
|
|
hook_destroy(cfg->hook_log);
|
|
|
|
// Free the structure itself
|
|
free(cfg);
|
|
}
|
|
|
|
/**
|
|
* Registers a transaction_start callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_transaction_start(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
|
|
hook_register(&cfg->hook_transaction_start, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a request_line callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_request_line(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
|
|
hook_register(&cfg->hook_request_line, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a request_headers callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_request_headers(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
|
|
hook_register(&cfg->hook_request_headers, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a request_trailer callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_request_trailer(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
|
|
hook_register(&cfg->hook_request_trailer, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a request_body_data callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_request_body_data(htp_cfg_t *cfg, int (*callback_fn)(htp_tx_data_t *)) {
|
|
hook_register(&cfg->hook_request_body_data, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a request callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_request(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
|
|
hook_register(&cfg->hook_request, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a request_line callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_response_line(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
|
|
hook_register(&cfg->hook_response_line, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a request_headers callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_response_headers(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
|
|
hook_register(&cfg->hook_response_headers, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a request_trailer callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_response_trailer(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
|
|
hook_register(&cfg->hook_response_trailer, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a request_body_data callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_response_body_data(htp_cfg_t *cfg, int (*callback_fn)(htp_tx_data_t *)) {
|
|
hook_register(&cfg->hook_response_body_data, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a request callback.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_response(htp_cfg_t *cfg, int (*callback_fn)(htp_connp_t *)) {
|
|
hook_register(&cfg->hook_response, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Registers a callback that is invoked every time there is a log message.
|
|
*
|
|
* @param cfg
|
|
* @param callback_fn
|
|
*/
|
|
void htp_config_register_log(htp_cfg_t *cfg, int (*callback_fn)(htp_log_t *)) {
|
|
hook_register(&cfg->hook_log, callback_fn);
|
|
}
|
|
|
|
/**
|
|
* Update the best-fit map, which is used to convert UCS-2 characters into
|
|
* single-byte characters. By default a Windows 1252 best-fit map is used. The map
|
|
* is an list of triplets, the first 2 bytes being an UCS-2 character to map from,
|
|
* and the third byte being the single byte to map to. Make sure that your map contains
|
|
* the mappings to cover the fullwidth form characters (U+FF00-FFEF).
|
|
*
|
|
* @param cfg
|
|
* @param map
|
|
*/
|
|
void htp_config_set_bestfit_map(htp_cfg_t *cfg, unsigned char *map) {
|
|
cfg->path_u_bestfit_map = map;
|
|
}
|
|
|
|
/**
|
|
* Whether to generate the request_uri_normalized field.
|
|
*
|
|
* @param cfg
|
|
* @param generate
|
|
*/
|
|
void htp_config_set_generate_request_uri_normalized(htp_cfg_t *cfg, int generate) {
|
|
cfg->generate_request_uri_normalized = generate;
|
|
}
|
|
|
|
/**
|
|
* Configures whether backslash characters are treated as path segment separators. They
|
|
* are not on Unix systems, but are on Windows systems. If this setting is enabled, a path
|
|
* such as "/one\two/three" will be converted to "/one/two/three".
|
|
*
|
|
* @param cfg
|
|
* @param backslash_separators
|
|
*/
|
|
void htp_config_set_path_backslash_separators(htp_cfg_t *cfg, int backslash_separators) {
|
|
cfg->path_backslash_separators = backslash_separators;
|
|
}
|
|
|
|
/**
|
|
* Configures filesystem sensitivity. This setting affects
|
|
* how URL paths are normalized. There are no path modifications by default, but
|
|
* on a case-insensitive systems path will be converted to lowercase.
|
|
*
|
|
* @param cfg
|
|
* @param case_insensitive
|
|
*/
|
|
void htp_config_set_path_case_insensitive(htp_cfg_t *cfg, int case_insensitive) {
|
|
cfg->path_case_insensitive = case_insensitive;
|
|
}
|
|
|
|
/**
|
|
* Configures whether consecutive path segment separators will be compressed. When
|
|
* enabled, a path such as "/one//two" will be normalized to "/one/two". The backslash_separators
|
|
* and decode_separators parameters are used before compression takes place. For example, if
|
|
* backshasl_deparators and decode_separators are both enabled, the path "/one\\/two\/%5cthree/%2f//four"
|
|
* will be converted to "/one/two/three/four".
|
|
*
|
|
* @param cfg
|
|
* @param compress_separators
|
|
*/
|
|
void htp_config_set_path_compress_separators(htp_cfg_t *cfg, int compress_separators) {
|
|
cfg->path_compress_separators = compress_separators;
|
|
}
|
|
|
|
/**
|
|
* This parameter is used to predict how a server will react when control
|
|
* characters are present in a request path, but does not affect path
|
|
* normalization.
|
|
*
|
|
* @param cfg
|
|
* @param control_char_handling Use NONE with servers that ignore control characters in
|
|
* request path, and STATUS_400 with servers that respond
|
|
* with 400.
|
|
*/
|
|
void htp_config_set_path_control_char_handling(htp_cfg_t *cfg, int control_char_handling) {
|
|
cfg->path_control_char_handling = control_char_handling;
|
|
}
|
|
|
|
/**
|
|
* Controls the UTF-8 treatment of request paths. One option is to only validate
|
|
* path as UTF-8. In this case, the UTF-8 flags will be raised as appropriate, and
|
|
* the path will remain in UTF-8 (if it was UTF-8in the first place). The other option
|
|
* is to convert a UTF-8 path into a single byte stream using best-fit mapping.
|
|
*
|
|
* @param cfg
|
|
* @param convert_utf8
|
|
*/
|
|
void htp_config_set_path_convert_utf8(htp_cfg_t *cfg, int convert_utf8) {
|
|
cfg->path_convert_utf8 = convert_utf8;
|
|
}
|
|
|
|
/**
|
|
* Configures whether encoded path segment separators will be decoded. Apache does
|
|
* not do this, but IIS does. If enabled, a path such as "/one%2ftwo" will be normalized
|
|
* to "/one/two". If the backslash_separators option is also enabled, encoded backslash
|
|
* characters will be converted too (and subseqently normalized to forward slashes).
|
|
*
|
|
* @param cfg
|
|
* @param decode_separators
|
|
*/
|
|
void htp_config_set_path_decode_separators(htp_cfg_t *cfg, int decode_separators) {
|
|
cfg->path_decode_separators = decode_separators;
|
|
}
|
|
|
|
/**
|
|
* Configures whether %u-encoded sequences in path will be decoded. Such sequences
|
|
* will be treated as invalid URL encoding if decoding is not desireable.
|
|
*
|
|
* @param cfg
|
|
* @param decode_u_encoding
|
|
*/
|
|
void htp_config_set_path_decode_u_encoding(htp_cfg_t *cfg, int decode_u_encoding) {
|
|
cfg->path_decode_u_encoding = decode_u_encoding;
|
|
}
|
|
|
|
/**
|
|
* Configures how server reacts to invalid encoding in path.
|
|
*
|
|
* @param cfg
|
|
* @param invalid_encoding_handling The available options are: URL_DECODER_PRESERVE_PERCENT,
|
|
* URL_DECODER_REMOVE_PERCENT, URL_DECODER_DECODE_INVALID
|
|
* and URL_DECODER_STATUS_400.
|
|
*/
|
|
void htp_config_set_path_invalid_encoding_handling(htp_cfg_t *cfg, int invalid_encoding_handling) {
|
|
cfg->path_invalid_encoding_handling = invalid_encoding_handling;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Configures how server reacts to invalid UTF-8 characters in path. This setting will
|
|
* not affect path normalization; it only controls what response status we expect for
|
|
* a request that contains invalid UTF-8 characters.
|
|
*
|
|
* @param cfg
|
|
* @param invalid_utf8_handling Possible values: NONE or STATUS_400.
|
|
*/
|
|
void htp_config_set_path_invalid_utf8_handling(htp_cfg_t *cfg, int invalid_utf8_handling) {
|
|
cfg->path_invalid_utf8_handling = invalid_utf8_handling;
|
|
}
|
|
|
|
/**
|
|
* Configures how server reacts to encoded NUL bytes. Some servers will terminate
|
|
* path at NUL, while some will respond with 400 or 404. When the termination option
|
|
* is not used, the NUL byte will remain in the path.
|
|
*
|
|
* @param cfg
|
|
* @param nul_encoded_handling Possible values: TERMINATE, STATUS_400, STATUS_404
|
|
*/
|
|
void htp_config_set_path_nul_encoded_handling(htp_cfg_t *cfg, int nul_encoded_handling) {
|
|
cfg->path_nul_encoded_handling = nul_encoded_handling;
|
|
}
|
|
|
|
/**
|
|
* Configures how server reacts to raw NUL bytes. Some servers will terminate
|
|
* path at NUL, while some will respond with 400 or 404. When the termination option
|
|
* is not used, the NUL byte will remain in the path.
|
|
*
|
|
* @param cfg
|
|
* @param nul_raw_handling Possible values: TERMINATE, STATUS_400, STATUS_404
|
|
*/
|
|
void htp_config_set_path_nul_raw_handling(htp_cfg_t *cfg, int nul_raw_handling) {
|
|
cfg->path_nul_raw_handling = nul_raw_handling;
|
|
}
|
|
|
|
/**
|
|
* Sets the replacement characater that will be used to in the lossy best-fit
|
|
* mapping from Unicode characters into single-byte streams. The question mark
|
|
* is the default replacement character.
|
|
*
|
|
* @param cfg
|
|
* @param replacement_char
|
|
*/
|
|
void htp_config_set_path_replacement_char(htp_cfg_t *cfg, int replacement_char) {
|
|
cfg->path_replacement_char = replacement_char;
|
|
}
|
|
|
|
/**
|
|
* Controls what the library does when it encounters an Unicode character where
|
|
* only a single-byte would do (e.g., the %u-encoded characters). Conversion always
|
|
* takes place; this parameter is used to correctly predict the status code used
|
|
* in response. In the future there will probably be an option to convert such
|
|
* characters to UCS-2 or UTF-8.
|
|
*
|
|
* @param cfg
|
|
* @param unicode_mapping Possible values: BESTFIT, STATUS_400, STATUS_404.
|
|
*/
|
|
void htp_config_set_path_unicode_mapping(htp_cfg_t *cfg, int unicode_mapping) {
|
|
cfg->path_unicode_mapping = unicode_mapping;
|
|
}
|
|
|
|
/**
|
|
* Controls how server reacts to overlong UTF-8 characters.
|
|
* XXX Not used at the moment.
|
|
*
|
|
* @param cfg
|
|
* @param utf8_overlong_handling
|
|
*/
|
|
void htp_config_set_path_utf8_overlong_handling(htp_cfg_t *cfg, int utf8_overlong_handling) {
|
|
cfg->path_utf8_overlong_handling = utf8_overlong_handling;
|
|
}
|
|
|
|
/**
|
|
* Configure desired server personality.
|
|
*
|
|
* @param cfg
|
|
* @param personality
|
|
* @return HTP_OK if the personality is supported, HTP_ERROR if it isn't.
|
|
*/
|
|
int htp_config_set_server_personality(htp_cfg_t *cfg, int personality) {
|
|
switch (personality) {
|
|
case HTP_SERVER_MINIMAL:
|
|
cfg->parse_request_line = htp_parse_request_line_generic;
|
|
cfg->process_request_header = htp_process_request_header_generic;
|
|
cfg->parse_response_line = htp_parse_response_line_generic;
|
|
cfg->process_response_header = htp_process_response_header_generic;
|
|
break;
|
|
|
|
case HTP_SERVER_GENERIC:
|
|
cfg->parse_request_line = htp_parse_request_line_generic;
|
|
cfg->process_request_header = htp_process_request_header_generic;
|
|
cfg->parse_response_line = htp_parse_response_line_generic;
|
|
cfg->process_response_header = htp_process_response_header_generic;
|
|
|
|
cfg->path_backslash_separators = YES;
|
|
cfg->path_decode_separators = YES;
|
|
cfg->path_compress_separators = YES;
|
|
break;
|
|
|
|
case HTP_SERVER_IDS:
|
|
cfg->parse_request_line = htp_parse_request_line_generic;
|
|
cfg->process_request_header = htp_process_request_header_generic;
|
|
cfg->parse_response_line = htp_parse_response_line_generic;
|
|
cfg->process_response_header = htp_process_response_header_generic;
|
|
|
|
cfg->path_backslash_separators = YES;
|
|
cfg->path_case_insensitive = YES;
|
|
cfg->path_decode_separators = YES;
|
|
cfg->path_compress_separators = YES;
|
|
cfg->path_decode_u_encoding = YES;
|
|
cfg->path_unicode_mapping = BESTFIT;
|
|
cfg->path_convert_utf8 = YES;
|
|
break;
|
|
|
|
case HTP_SERVER_APACHE :
|
|
case HTP_SERVER_APACHE_2_2:
|
|
cfg->parse_request_line = htp_parse_request_line_apache_2_2;
|
|
cfg->process_request_header = htp_process_request_header_apache_2_2;
|
|
cfg->parse_response_line = htp_parse_response_line_generic;
|
|
cfg->process_response_header = htp_process_response_header_generic;
|
|
|
|
cfg->path_backslash_separators = NO;
|
|
cfg->path_decode_separators = NO;
|
|
cfg->path_compress_separators = YES;
|
|
cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;
|
|
cfg->path_control_char_handling = NONE;
|
|
break;
|
|
|
|
case HTP_SERVER_IIS_5_1:
|
|
cfg->parse_request_line = htp_parse_request_line_generic;
|
|
cfg->process_request_header = htp_process_request_header_generic;
|
|
cfg->parse_response_line = htp_parse_response_line_generic;
|
|
cfg->process_response_header = htp_process_response_header_generic;
|
|
|
|
cfg->path_backslash_separators = YES;
|
|
cfg->path_decode_separators = NO;
|
|
cfg->path_compress_separators = YES;
|
|
cfg->path_invalid_encoding_handling = URL_DECODER_PRESERVE_PERCENT;
|
|
cfg->path_decode_u_encoding = YES;
|
|
cfg->path_unicode_mapping = BESTFIT;
|
|
cfg->path_control_char_handling = NONE;
|
|
break;
|
|
|
|
case HTP_SERVER_IIS_6_0:
|
|
cfg->parse_request_line = htp_parse_request_line_generic;
|
|
cfg->process_request_header = htp_process_request_header_generic;
|
|
cfg->parse_response_line = htp_parse_response_line_generic;
|
|
cfg->process_response_header = htp_process_response_header_generic;
|
|
|
|
cfg->path_backslash_separators = YES;
|
|
cfg->path_decode_separators = YES;
|
|
cfg->path_compress_separators = YES;
|
|
cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;
|
|
cfg->path_decode_u_encoding = YES;
|
|
cfg->path_unicode_mapping = STATUS_400;
|
|
cfg->path_control_char_handling = STATUS_400;
|
|
break;
|
|
|
|
case HTP_SERVER_IIS_7_0:
|
|
case HTP_SERVER_IIS_7_5:
|
|
cfg->parse_request_line = htp_parse_request_line_generic;
|
|
cfg->process_request_header = htp_process_request_header_generic;
|
|
cfg->parse_response_line = htp_parse_response_line_generic;
|
|
cfg->process_response_header = htp_process_response_header_generic;
|
|
|
|
cfg->path_backslash_separators = YES;
|
|
cfg->path_decode_separators = YES;
|
|
cfg->path_compress_separators = YES;
|
|
cfg->path_invalid_encoding_handling = URL_DECODER_STATUS_400;
|
|
cfg->path_control_char_handling = STATUS_400;
|
|
break;
|
|
|
|
default:
|
|
return HTP_ERROR;
|
|
}
|
|
|
|
// Remember the personality
|
|
cfg->spersonality = personality;
|
|
|
|
return HTP_OK;
|
|
}
|