mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-15 23:55:03 +03:00
Fixes, code cleanups, improvements
This commit is contained in:
parent
0b3ed41812
commit
6b7edc4d47
208
apache2/acmp.c
208
apache2/acmp.c
@ -263,33 +263,6 @@ static void acmp_clone_node_no_state(acmp_node_t *from, acmp_node_t *to) {
|
|||||||
to->hit_count = 0;
|
to->hit_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies sibling nodes and child node for from given "from" node to "to" node.
|
|
||||||
* Both nodes must already exist.
|
|
||||||
*/
|
|
||||||
static void acmp_copy_nodes_recursive(acmp_node_t *from, acmp_node_t *to, apr_pool_t *pool) {
|
|
||||||
acmp_node_t *old_node = from->child, *new_node, *nn2;
|
|
||||||
if (old_node == NULL) return;
|
|
||||||
nn2 = apr_pcalloc(pool, sizeof(acmp_node_t));
|
|
||||||
/* ENH: Check alloc succeded */
|
|
||||||
acmp_clone_node_no_state(old_node, nn2);
|
|
||||||
nn2->parent = to;
|
|
||||||
to->child = nn2;
|
|
||||||
acmp_copy_nodes_recursive(from->child, to->child, pool);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
old_node = old_node->sibling;
|
|
||||||
if (old_node == NULL) break;
|
|
||||||
new_node = apr_pcalloc(pool, sizeof(acmp_node_t));
|
|
||||||
/* ENH: Check alloc succeded */
|
|
||||||
acmp_clone_node_no_state(old_node, new_node);
|
|
||||||
new_node->parent = to;
|
|
||||||
nn2->sibling = new_node;
|
|
||||||
nn2 = new_node;
|
|
||||||
acmp_copy_nodes_recursive(old_node, new_node, pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline acmp_node_t *acmp_btree_find(acmp_node_t *node, acmp_utf8_char_t letter) {
|
static inline acmp_node_t *acmp_btree_find(acmp_node_t *node, acmp_utf8_char_t letter) {
|
||||||
acmp_btree_node_t *bnode = node->btree;
|
acmp_btree_node_t *bnode = node->btree;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -465,29 +438,6 @@ static apr_status_t acmp_connect_fail_branches(ACMP *parser) {
|
|||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears hit count of each node, called from acmp_reset()
|
|
||||||
*/
|
|
||||||
static void acmp_clear_hit_count_recursive(acmp_node_t *node) {
|
|
||||||
for (; node != NULL; node = node->sibling) {
|
|
||||||
node->hit_count = 0;
|
|
||||||
if (node->child != NULL) acmp_clear_hit_count_recursive(node->child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a match is found
|
|
||||||
*/
|
|
||||||
static void acmp_found(ACMP *parser, acmp_node_t *node) {
|
|
||||||
if (node->callback) {
|
|
||||||
node->callback(parser, node->callback_data,
|
|
||||||
parser->bp_buffer[(parser->char_pos - node->depth - 1) % parser->bp_buff_len],
|
|
||||||
parser->char_pos - node->depth - 1);
|
|
||||||
}
|
|
||||||
node->hit_count++;
|
|
||||||
parser->hit_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
@ -520,48 +470,6 @@ ACMP *acmp_create(int flags, apr_pool_t *pool) {
|
|||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroys previously created parser
|
|
||||||
*/
|
|
||||||
void acmp_destroy(ACMP *parser) {
|
|
||||||
/*
|
|
||||||
* All data is kept in parser's pool (including parser struct itself), so
|
|
||||||
* destroying the pool will destroy everything
|
|
||||||
*/
|
|
||||||
apr_pool_destroy(parser->pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates parser with same options and same patterns
|
|
||||||
* parser - ACMP parser to duplicate
|
|
||||||
* pool - parent pool to use, if left as NULL original parser's parent pool is used
|
|
||||||
*/
|
|
||||||
ACMP *acmp_duplicate(ACMP *parser, apr_pool_t *pool) {
|
|
||||||
apr_status_t rc;
|
|
||||||
apr_pool_t *p;
|
|
||||||
ACMP *new_parser;
|
|
||||||
|
|
||||||
if (pool == NULL) pool = parser->parent_pool;
|
|
||||||
rc = apr_pool_create(&p, pool);
|
|
||||||
if (rc != APR_SUCCESS) return NULL;
|
|
||||||
|
|
||||||
new_parser = apr_pcalloc(p, sizeof(ACMP));
|
|
||||||
/* ENH: Check alloc succeded */
|
|
||||||
new_parser->pool = p;
|
|
||||||
new_parser->parent_pool = pool;
|
|
||||||
#ifdef ACMP_USE_UTF8
|
|
||||||
new_parser->is_utf8 = parser->is_utf8;
|
|
||||||
#endif
|
|
||||||
new_parser->is_case_sensitive = parser->is_case_sensitive;
|
|
||||||
new_parser->root_node = apr_pcalloc(p, sizeof(acmp_node_t));
|
|
||||||
/* ENH: Check alloc succeded */
|
|
||||||
new_parser->dict_count = parser->dict_count;
|
|
||||||
new_parser->longest_entry = parser->longest_entry;
|
|
||||||
acmp_copy_nodes_recursive(parser->root_node, new_parser->root_node, new_parser->pool);
|
|
||||||
acmp_prepare(new_parser);
|
|
||||||
return new_parser;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates fail tree and initializes buffer
|
* Creates fail tree and initializes buffer
|
||||||
*/
|
*/
|
||||||
@ -642,122 +550,6 @@ apr_status_t acmp_add_pattern(ACMP *parser, const char *pattern,
|
|||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to process incoming data stream
|
|
||||||
* data - ptr to incoming data
|
|
||||||
* len - size of data in bytes
|
|
||||||
*/
|
|
||||||
apr_status_t acmp_process(ACMP *parser, const char *data, apr_size_t len) {
|
|
||||||
acmp_node_t *node, *go_to;
|
|
||||||
#ifdef ACMP_USE_UTF8
|
|
||||||
apr_size_t seq_length;
|
|
||||||
#endif
|
|
||||||
const char *end;
|
|
||||||
|
|
||||||
if (parser->is_failtree_done == 0) acmp_prepare(parser);
|
|
||||||
|
|
||||||
node = parser->active_node;
|
|
||||||
end = data + len;
|
|
||||||
|
|
||||||
while (data < end) {
|
|
||||||
acmp_utf8_char_t letter;
|
|
||||||
|
|
||||||
parser->bp_buffer[parser->char_pos % parser->bp_buff_len] = parser->byte_pos;
|
|
||||||
#ifdef ACMP_USE_UTF8
|
|
||||||
if (parser->is_utf8) {
|
|
||||||
if (parser->u8buff_len > 0) {
|
|
||||||
/* Resuming partial utf-8 sequence */
|
|
||||||
seq_length = utf8_seq_len(parser->u8_buff);
|
|
||||||
for (;;) {
|
|
||||||
parser->u8_buff[parser->u8buff_len++] = *data++;
|
|
||||||
if (parser->u8buff_len == seq_length) {
|
|
||||||
parser->u8buff_len = 0;
|
|
||||||
letter = utf8_decodechar(parser->u8_buff);
|
|
||||||
parser->byte_pos += seq_length;
|
|
||||||
parser->char_pos++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* not resuming partial sequence, reading from the stream */
|
|
||||||
seq_length = utf8_seq_len(data);
|
|
||||||
if ((data + seq_length) > end) {
|
|
||||||
while (data < end) parser->u8_buff[parser->u8buff_len++] = *data++;
|
|
||||||
return APR_SUCCESS;
|
|
||||||
} else {
|
|
||||||
letter = utf8_decodechar(data);
|
|
||||||
data += seq_length;
|
|
||||||
parser->byte_pos += seq_length;
|
|
||||||
parser->char_pos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
letter = *data++;
|
|
||||||
parser->byte_pos++;
|
|
||||||
parser->char_pos++;
|
|
||||||
}
|
|
||||||
if (parser->is_case_sensitive == 0) letter = utf8_lcase(letter);
|
|
||||||
|
|
||||||
go_to = NULL;
|
|
||||||
while (go_to == NULL) {
|
|
||||||
acmp_node_t *n2 = acmp_goto(node, letter);
|
|
||||||
go_to = acmp_child_for_code(node, letter);
|
|
||||||
if (n2 != go_to) {
|
|
||||||
n2 = acmp_goto(node, letter);
|
|
||||||
};
|
|
||||||
if (go_to != NULL) {
|
|
||||||
if (go_to->is_last) {
|
|
||||||
acmp_found(parser, go_to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (node == parser->root_node) break;
|
|
||||||
if (go_to == NULL) node = node->fail;
|
|
||||||
}
|
|
||||||
if (go_to != NULL) node = go_to;
|
|
||||||
|
|
||||||
/* We need to collect other nodes that are last letters of phrase. These
|
|
||||||
* will be fail node of current node if it has is_last flag set, and
|
|
||||||
* fail node of that node, recursively down to root node.
|
|
||||||
*/
|
|
||||||
go_to = node;
|
|
||||||
if (go_to != parser->root_node) {
|
|
||||||
for (go_to = go_to->o_match; go_to != NULL; go_to = go_to->o_match) {
|
|
||||||
acmp_found(parser, go_to);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parser->active_node = node;
|
|
||||||
return parser->hit_count > 0 ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the state of parser so you can start using it with new set of data.
|
|
||||||
*
|
|
||||||
* No need to clear buffer since it will be re-initialized at first run of
|
|
||||||
* acmp_process
|
|
||||||
*/
|
|
||||||
void acmp_reset(ACMP *parser) {
|
|
||||||
parser->is_active = 0;
|
|
||||||
parser->byte_pos = 0;
|
|
||||||
parser->char_pos = 0;
|
|
||||||
parser->hit_count = 0;
|
|
||||||
parser->u8buff_len = 0;
|
|
||||||
acmp_clear_hit_count_recursive(parser->root_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an ACMPT struct that will use parser's tree, without duplicating its data
|
|
||||||
*/
|
|
||||||
ACMPT *acmp_duplicate_quick(ACMP *parser, apr_pool_t *pool) {
|
|
||||||
apr_pool_t *p = (pool != NULL) ? pool : parser->pool;
|
|
||||||
ACMPT *dup = apr_pcalloc(p, sizeof(ACMPT));
|
|
||||||
/* ENH: Check alloc succeded */
|
|
||||||
dup->parser = parser;
|
|
||||||
return dup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the data using ACMPT to keep state, and ACMPT's parser to keep the tree
|
* Process the data using ACMPT to keep state, and ACMPT's parser to keep the tree
|
||||||
*/
|
*/
|
||||||
|
@ -84,12 +84,6 @@ char DSOLOCAL *get_apr_error(apr_pool_t *p, apr_status_t rc);
|
|||||||
|
|
||||||
char DSOLOCAL *get_env_var(request_rec *r, char *name);
|
char DSOLOCAL *get_env_var(request_rec *r, char *name);
|
||||||
|
|
||||||
void DSOLOCAL internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *msr,
|
|
||||||
int level, int fixup, const char *text, va_list ap);
|
|
||||||
|
|
||||||
void DSOLOCAL internal_log(request_rec *r, directory_config *dcfg, modsec_rec *msr,
|
|
||||||
int level, const char *text, va_list ap);
|
|
||||||
|
|
||||||
void DSOLOCAL msr_log(modsec_rec *msr, int level, const char *text, ...) PRINTF_ATTRIBUTE(3,4);
|
void DSOLOCAL msr_log(modsec_rec *msr, int level, const char *text, ...) PRINTF_ATTRIBUTE(3,4);
|
||||||
|
|
||||||
void DSOLOCAL msr_log_error(modsec_rec *msr, const char *text, ...) PRINTF_ATTRIBUTE(2,3);
|
void DSOLOCAL msr_log_error(modsec_rec *msr, const char *text, ...) PRINTF_ATTRIBUTE(2,3);
|
||||||
|
@ -192,7 +192,7 @@ char *get_env_var(request_rec *r, char *name) {
|
|||||||
* true, the message will be stripped of any trailing newline and any
|
* true, the message will be stripped of any trailing newline and any
|
||||||
* required bytes will be escaped.
|
* required bytes will be escaped.
|
||||||
*/
|
*/
|
||||||
void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *msr,
|
static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *msr,
|
||||||
int level, int fixup, const char *text, va_list ap)
|
int level, int fixup, const char *text, va_list ap)
|
||||||
{
|
{
|
||||||
apr_size_t nbytes, nbytes_written;
|
apr_size_t nbytes, nbytes_written;
|
||||||
@ -279,15 +279,6 @@ void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *msr,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal log helper function. Use msr_log instead.
|
|
||||||
*/
|
|
||||||
void internal_log(request_rec *r, directory_config *dcfg, modsec_rec *msr,
|
|
||||||
int level, const char *text, va_list ap)
|
|
||||||
{
|
|
||||||
internal_log_ex(r, dcfg, msr, level, 0, text, ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs one message at the given level to the debug log (and to the
|
* Logs one message at the given level to the debug log (and to the
|
||||||
* Apache error log if the message is important enough.
|
* Apache error log if the message is important enough.
|
||||||
|
@ -41,11 +41,9 @@ msc_engine DSOLOCAL *modsecurity = NULL;
|
|||||||
|
|
||||||
char DSOLOCAL *chroot_dir = NULL;
|
char DSOLOCAL *chroot_dir = NULL;
|
||||||
|
|
||||||
unsigned int DSOLOCAL chroot_completed = 0;
|
|
||||||
|
|
||||||
char DSOLOCAL *new_server_signature = NULL;
|
char DSOLOCAL *new_server_signature = NULL;
|
||||||
|
|
||||||
char DSOLOCAL *real_server_signature = NULL;
|
static char *real_server_signature = NULL;
|
||||||
|
|
||||||
char DSOLOCAL *guardianlog_name = NULL;
|
char DSOLOCAL *guardianlog_name = NULL;
|
||||||
|
|
||||||
@ -73,7 +71,7 @@ typedef struct {
|
|||||||
*
|
*
|
||||||
* \param mp Pointer to memory pool
|
* \param mp Pointer to memory pool
|
||||||
*/
|
*/
|
||||||
void version(apr_pool_t *mp) {
|
static void version(apr_pool_t *mp) {
|
||||||
char *pcre_vrs = NULL;
|
char *pcre_vrs = NULL;
|
||||||
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
|
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
|
||||||
@ -592,8 +590,6 @@ static int hook_post_config(apr_pool_t *mp, apr_pool_t *mp_log, apr_pool_t *mp_t
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
chroot_completed = 1;
|
|
||||||
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_NOTICE | APLOG_NOERRNO, 0, s,
|
ap_log_error(APLOG_MARK, APLOG_NOTICE | APLOG_NOERRNO, 0, s,
|
||||||
"ModSecurity: chroot successful, path=%s", chroot_dir);
|
"ModSecurity: chroot successful, path=%s", chroot_dir);
|
||||||
} else {
|
} else {
|
||||||
@ -1297,19 +1293,19 @@ static void modsec_register_reqbody_processor(const char *name,
|
|||||||
* Registers module hooks with Apache.
|
* Registers module hooks with Apache.
|
||||||
*/
|
*/
|
||||||
static void register_hooks(apr_pool_t *mp) {
|
static void register_hooks(apr_pool_t *mp) {
|
||||||
static const char *postconfig_beforeme_list[] = {
|
static const char *const postconfig_beforeme_list[] = {
|
||||||
"mod_unique_id.c",
|
"mod_unique_id.c",
|
||||||
"mod_ssl.c",
|
"mod_ssl.c",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *postconfig_afterme_list[] = {
|
static const char *const postconfig_afterme_list[] = {
|
||||||
"mod_fcgid.c",
|
"mod_fcgid.c",
|
||||||
"mod_cgid.c",
|
"mod_cgid.c",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *postread_beforeme_list[] = {
|
static const char *const postread_beforeme_list[] = {
|
||||||
"mod_rpaf.c",
|
"mod_rpaf.c",
|
||||||
"mod_rpaf-2.0.c",
|
"mod_rpaf-2.0.c",
|
||||||
"mod_extract_forwarded2.c",
|
"mod_extract_forwarded2.c",
|
||||||
@ -1321,12 +1317,12 @@ static void register_hooks(apr_pool_t *mp) {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *postread_afterme_list[] = {
|
static const char *const postread_afterme_list[] = {
|
||||||
"mod_log_forensic.c",
|
"mod_log_forensic.c",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *transaction_afterme_list[] = {
|
static const char *const transaction_afterme_list[] = {
|
||||||
"mod_log_config.c",
|
"mod_log_config.c",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -122,7 +122,6 @@ typedef struct msc_parm msc_parm;
|
|||||||
#define FATAL_ERROR "ModSecurity: Fatal error (memory allocation or unexpected internal error)!"
|
#define FATAL_ERROR "ModSecurity: Fatal error (memory allocation or unexpected internal error)!"
|
||||||
|
|
||||||
extern DSOLOCAL char *new_server_signature;
|
extern DSOLOCAL char *new_server_signature;
|
||||||
extern DSOLOCAL char *real_server_signature;
|
|
||||||
extern DSOLOCAL char *chroot_dir;
|
extern DSOLOCAL char *chroot_dir;
|
||||||
|
|
||||||
extern module AP_MODULE_DECLARE_DATA security2_module;
|
extern module AP_MODULE_DECLARE_DATA security2_module;
|
||||||
|
@ -152,7 +152,6 @@ static void create_segments(geo_db *geo) {
|
|||||||
unsigned char delim[3];
|
unsigned char delim[3];
|
||||||
unsigned char buf[GEO_SEGMENT_RECORD_LENGTH];
|
unsigned char buf[GEO_SEGMENT_RECORD_LENGTH];
|
||||||
apr_size_t nbytes;
|
apr_size_t nbytes;
|
||||||
apr_status_t rc;
|
|
||||||
apr_off_t offset;
|
apr_off_t offset;
|
||||||
|
|
||||||
geo->ctry_offset = 0;
|
geo->ctry_offset = 0;
|
||||||
@ -163,10 +162,10 @@ static void create_segments(geo_db *geo) {
|
|||||||
|
|
||||||
for (i = 0; i < GEO_STRUCT_INFO_MAX_SIZE; i++) {
|
for (i = 0; i < GEO_STRUCT_INFO_MAX_SIZE; i++) {
|
||||||
|
|
||||||
rc = apr_file_read_full(geo->db, &delim, 3, &nbytes);
|
apr_file_read_full(geo->db, &delim, 3, &nbytes);
|
||||||
|
|
||||||
if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) {
|
if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) {
|
||||||
rc = apr_file_read_full(geo->db, &geo->dbtype, 1, &nbytes);
|
apr_file_read_full(geo->db, &geo->dbtype, 1, &nbytes);
|
||||||
if (geo->dbtype >= 106) {
|
if (geo->dbtype >= 106) {
|
||||||
geo->dbtype -= 105;
|
geo->dbtype -= 105;
|
||||||
}
|
}
|
||||||
@ -181,7 +180,7 @@ static void create_segments(geo_db *geo) {
|
|||||||
geo->dbtype == GEOIP_ISP_EDITION ||
|
geo->dbtype == GEOIP_ISP_EDITION ||
|
||||||
geo->dbtype == GEOIP_ASNUM_EDITION) {
|
geo->dbtype == GEOIP_ASNUM_EDITION) {
|
||||||
geo->ctry_offset = 0;
|
geo->ctry_offset = 0;
|
||||||
rc = apr_file_read_full(geo->db, &buf, GEO_SEGMENT_RECORD_LENGTH, &nbytes);
|
apr_file_read_full(geo->db, &buf, GEO_SEGMENT_RECORD_LENGTH, &nbytes);
|
||||||
for (j = 0; j < GEO_SEGMENT_RECORD_LENGTH; j++) {
|
for (j = 0; j < GEO_SEGMENT_RECORD_LENGTH; j++) {
|
||||||
geo->ctry_offset += (buf[j] << (j * 8));
|
geo->ctry_offset += (buf[j] << (j * 8));
|
||||||
}
|
}
|
||||||
@ -530,12 +529,4 @@ int geo_lookup(modsec_rec *msr, geo_rec *georec, const char *target, char **erro
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Frees the resources used for Geo lookups
|
|
||||||
*/
|
|
||||||
apr_status_t geo_cleanup(modsec_rec *msr)
|
|
||||||
{
|
|
||||||
return APR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,6 +67,4 @@ int DSOLOCAL geo_init(directory_config *dcfg, const char *dbfn, char **error_msg
|
|||||||
|
|
||||||
int DSOLOCAL geo_lookup(modsec_rec *msr, geo_rec *rec, const char *target, char **error_msg);
|
int DSOLOCAL geo_lookup(modsec_rec *msr, geo_rec *rec, const char *target, char **error_msg);
|
||||||
|
|
||||||
apr_status_t DSOLOCAL geo_cleanup(modsec_rec *msr);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -68,51 +68,6 @@ static int sec_auditlog_write(modsec_rec *msr, const char *data, unsigned int le
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a log line in the vcombinedus format (see below).
|
|
||||||
*/
|
|
||||||
char *construct_log_vcombinedus(modsec_rec *msr) {
|
|
||||||
const char *local_user, *remote_user;
|
|
||||||
const char *referer, *user_agent, *uniqueid;
|
|
||||||
const char *sessionid;
|
|
||||||
|
|
||||||
/* remote log name */
|
|
||||||
if (msr->remote_user == NULL) remote_user = "-";
|
|
||||||
else remote_user = msr->remote_user;
|
|
||||||
|
|
||||||
/* authenticated user */
|
|
||||||
if (msr->local_user == NULL) local_user = "-";
|
|
||||||
else local_user = msr->local_user;
|
|
||||||
|
|
||||||
/* unique id */
|
|
||||||
uniqueid = msr->txid;
|
|
||||||
if (uniqueid == NULL) uniqueid = "-";
|
|
||||||
|
|
||||||
/* referer */
|
|
||||||
referer = "-";
|
|
||||||
/* Logging Referer is a waste of space.
|
|
||||||
referer = (char *)apr_table_get(msr->request_headers, "Referer");
|
|
||||||
if (referer == NULL) referer = "-";
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* user agent */
|
|
||||||
user_agent = "-";
|
|
||||||
/* Logging User-Agent is a waste of space too.
|
|
||||||
user_agent = (char *)apr_table_get(msr->request_headers, "User-Agent");
|
|
||||||
if (user_agent == NULL) user_agent = "-";
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* sessionid */
|
|
||||||
sessionid = (msr->sessionid == NULL ? "-" : msr->sessionid);
|
|
||||||
|
|
||||||
return apr_psprintf(msr->mp, "%s %s %s %s [%s] \"%s\" %u %" APR_OFF_T_FMT " \"%s\" \"%s\" %s \"%s\"",
|
|
||||||
log_escape_nq(msr->mp, msr->hostname), msr->remote_addr, log_escape_nq(msr->mp, remote_user),
|
|
||||||
log_escape_nq(msr->mp, local_user), current_logtime(msr->mp),
|
|
||||||
((msr->request_line == NULL) ? "" : log_escape(msr->mp, msr->request_line)),
|
|
||||||
msr->response_status, msr->bytes_sent, log_escape(msr->mp, referer),
|
|
||||||
log_escape(msr->mp, user_agent), log_escape(msr->mp, uniqueid), sessionid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a log line in vcombined log format trying to truncate
|
* Constructs a log line in vcombined log format trying to truncate
|
||||||
* some of the fields to make the log line shorter than _limit bytes.
|
* some of the fields to make the log line shorter than _limit bytes.
|
||||||
@ -423,7 +378,7 @@ static void sec_auditlog_write_producer_header(modsec_rec *msr) {
|
|||||||
* \retval NULL On failure
|
* \retval NULL On failure
|
||||||
* \retval next_rule On Success
|
* \retval next_rule On Success
|
||||||
*/
|
*/
|
||||||
msre_rule *return_chained_rule(const msre_rule *current, modsec_rec *msr) {
|
static msre_rule *return_chained_rule(const msre_rule *current, modsec_rec *msr) {
|
||||||
apr_array_header_t *arr = NULL;
|
apr_array_header_t *arr = NULL;
|
||||||
msre_rule **rules = NULL;
|
msre_rule **rules = NULL;
|
||||||
msre_rule *rule = NULL, *next_rule = NULL;
|
msre_rule *rule = NULL, *next_rule = NULL;
|
||||||
@ -499,7 +454,7 @@ msre_rule *return_chained_rule(const msre_rule *current, modsec_rec *msr) {
|
|||||||
* \retval 0 On failure
|
* \retval 0 On failure
|
||||||
* \retval 1 On Success
|
* \retval 1 On Success
|
||||||
*/
|
*/
|
||||||
int chained_is_matched(modsec_rec *msr, const msre_rule *next_rule) {
|
static int chained_is_matched(modsec_rec *msr, const msre_rule *next_rule) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
const msre_rule *rule = NULL;
|
const msre_rule *rule = NULL;
|
||||||
|
|
||||||
@ -1110,13 +1065,13 @@ void sec_audit_logger(modsec_rec *msr) {
|
|||||||
for(cfiles = 0; cfiles < msr->mpd->parts->nelts; cfiles++) {
|
for(cfiles = 0; cfiles < msr->mpd->parts->nelts; cfiles++) {
|
||||||
if (parts[cfiles]->type == MULTIPART_FILE) {
|
if (parts[cfiles]->type == MULTIPART_FILE) {
|
||||||
if(parts[cfiles]->filename != NULL) {
|
if(parts[cfiles]->filename != NULL) {
|
||||||
text = apr_psprintf(msr->mp, "#%d Filename: %s - Size: %u - ContentType: %s\n", cfiles, log_escape_nq(msr->mp, parts[cfiles]->filename), parts[cfiles]->tmp_file_size, log_escape_nq(msr->mp, parts[cfiles]->content_type ? parts[cfiles]->content_type : "<Unknown ContentType>"));
|
text = apr_psprintf(msr->mp, "%d,%u,\"%s\",\"%s\"\n", cfiles+1, parts[cfiles]->tmp_file_size, log_escape_nq(msr->mp, parts[cfiles]->filename), log_escape_nq(msr->mp, parts[cfiles]->content_type ? parts[cfiles]->content_type : "<Unknown ContentType>"));
|
||||||
sec_auditlog_write(msr, text, strlen(text));
|
sec_auditlog_write(msr, text, strlen(text));
|
||||||
total_size += parts[cfiles]->tmp_file_size;
|
total_size += parts[cfiles]->tmp_file_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
text = apr_psprintf(msr->mp, "Total upload size: %u\n", total_size);
|
text = apr_psprintf(msr->mp, "Total,%u\n", total_size);
|
||||||
sec_auditlog_write(msr, text, strlen(text));
|
sec_auditlog_write(msr, text, strlen(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,8 +42,6 @@
|
|||||||
|
|
||||||
int DSOLOCAL is_valid_parts_specification(char *p);
|
int DSOLOCAL is_valid_parts_specification(char *p);
|
||||||
|
|
||||||
char DSOLOCAL *construct_log_vcombinedus(modsec_rec *msr);
|
|
||||||
|
|
||||||
char DSOLOCAL *construct_log_vcombinedus_limited(modsec_rec *msr, int _limit, int *was_limited);
|
char DSOLOCAL *construct_log_vcombinedus_limited(modsec_rec *msr, int _limit, int *was_limited);
|
||||||
|
|
||||||
void DSOLOCAL sec_audit_logger(modsec_rec *msr);
|
void DSOLOCAL sec_audit_logger(modsec_rec *msr);
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
/**
|
/**
|
||||||
* Releases the resources used by a single regular expression pattern.
|
* Releases the resources used by a single regular expression pattern.
|
||||||
*/
|
*/
|
||||||
apr_status_t msc_pcre_cleanup(msc_regex_t *regex) {
|
static apr_status_t msc_pcre_cleanup(msc_regex_t *regex) {
|
||||||
if (regex != NULL) {
|
if (regex != NULL) {
|
||||||
if (regex->pe != NULL) {
|
if (regex->pe != NULL) {
|
||||||
free(regex->pe);
|
free(regex->pe);
|
||||||
|
@ -38,8 +38,6 @@ struct msc_regex_t {
|
|||||||
const char *pattern;
|
const char *pattern;
|
||||||
};
|
};
|
||||||
|
|
||||||
apr_status_t DSOLOCAL msc_pcre_cleanup(msc_regex_t *regex);
|
|
||||||
|
|
||||||
void DSOLOCAL *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
|
void DSOLOCAL *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
|
||||||
const char **_errptr, int *_erroffset,
|
const char **_errptr, int *_erroffset,
|
||||||
int match_limit, int match_limit_recursion);
|
int match_limit, int match_limit_recursion);
|
||||||
|
@ -14,20 +14,22 @@
|
|||||||
|
|
||||||
#include "msc_release.h"
|
#include "msc_release.h"
|
||||||
|
|
||||||
modsec_build_type_rec modsec_build_type[] = {
|
static const struct modsec_build_type_rec {
|
||||||
|
char name[12]; /* pads at 16 bytes with val */
|
||||||
|
int val;
|
||||||
|
} modsec_build_type[] = {
|
||||||
{ "-dev", 1 }, /* Development build */
|
{ "-dev", 1 }, /* Development build */
|
||||||
{ "-rc", 3 }, /* Release Candidate build */
|
{ "-rc", 3 }, /* Release Candidate build */
|
||||||
{ "", 9 }, /* Production build */
|
{ "", 9 }, /* Production build */
|
||||||
{ "-tw", 9 }, /* Truswave Holdings build */
|
{ "-tw", 9 }, /* Truswave Holdings build */
|
||||||
{ "-trunk", 9 }, /* Trunk build */
|
{ "-trunk", 9 } /* Trunk build */
|
||||||
{ NULL, -1 } /* terminator */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int get_modsec_build_type(const char *name)
|
int get_modsec_build_type(const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; modsec_build_type[i].name != NULL; i++) {
|
for (i = 0; i < sizeof(modsec_build_type)/sizeof(modsec_build_type[0]); i++) {
|
||||||
if (strcmp(((name == NULL) ? MODSEC_VERSION_TYPE : name), modsec_build_type[i].name) == 0) {
|
if (strcmp(((name == NULL) ? MODSEC_VERSION_TYPE : name), modsec_build_type[i].name) == 0) {
|
||||||
return modsec_build_type[i].val;
|
return modsec_build_type[i].val;
|
||||||
}
|
}
|
||||||
|
@ -36,17 +36,11 @@
|
|||||||
#define PRINTF_ATTRIBUTE(a,b)
|
#define PRINTF_ATTRIBUTE(a,b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct modsec_build_type_rec {
|
|
||||||
const char * name;
|
|
||||||
int val;
|
|
||||||
} modsec_build_type_rec;
|
|
||||||
extern DSOLOCAL modsec_build_type_rec modsec_build_type[];
|
|
||||||
|
|
||||||
#define MODSEC_VERSION_MAJOR "2"
|
#define MODSEC_VERSION_MAJOR "2"
|
||||||
#define MODSEC_VERSION_MINOR "7"
|
#define MODSEC_VERSION_MINOR "6"
|
||||||
#define MODSEC_VERSION_MAINT "0"
|
#define MODSEC_VERSION_MAINT "0"
|
||||||
#define MODSEC_VERSION_TYPE "-trunk"
|
#define MODSEC_VERSION_TYPE "-rc"
|
||||||
#define MODSEC_VERSION_RELEASE ""
|
#define MODSEC_VERSION_RELEASE "2"
|
||||||
|
|
||||||
#define MODSEC_VERSION_SUFFIX MODSEC_VERSION_TYPE MODSEC_VERSION_RELEASE
|
#define MODSEC_VERSION_SUFFIX MODSEC_VERSION_TYPE MODSEC_VERSION_RELEASE
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
#define S_ISUID 04000
|
#define S_ISUID 04000
|
||||||
#endif /* defined(WIN32 || NETWARE) */
|
#endif /* defined(WIN32 || NETWARE) */
|
||||||
|
|
||||||
/* Base64 tables used in base64DecodeExt */
|
/* Base64 tables used in decodeBase64Ext */
|
||||||
static const char b64_pad = '=';
|
static const char b64_pad = '=';
|
||||||
|
|
||||||
static const short b64_reverse_t[256] = {
|
static const short b64_reverse_t[256] = {
|
||||||
@ -69,6 +69,10 @@ static const short b64_reverse_t[256] = {
|
|||||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
|
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static unsigned char *c2x(unsigned what, unsigned char *where);
|
||||||
|
static unsigned char x2c(unsigned char *what);
|
||||||
|
static unsigned char xsingle2c(unsigned char *what);
|
||||||
|
|
||||||
/* \brief Remove escape char
|
/* \brief Remove escape char
|
||||||
*
|
*
|
||||||
* \param mptmp Pointer to the pool
|
* \param mptmp Pointer to the pool
|
||||||
@ -515,7 +519,7 @@ int remove_lf_crlf_inplace(char *text) {
|
|||||||
* into a proper byte. Handles uppercase and lowercase letters
|
* into a proper byte. Handles uppercase and lowercase letters
|
||||||
* but does not check for overflows.
|
* but does not check for overflows.
|
||||||
*/
|
*/
|
||||||
unsigned char x2c(unsigned char *what) {
|
static unsigned char x2c(unsigned char *what) {
|
||||||
register unsigned char digit;
|
register unsigned char digit;
|
||||||
|
|
||||||
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
|
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
|
||||||
@ -528,7 +532,7 @@ unsigned char x2c(unsigned char *what) {
|
|||||||
/**
|
/**
|
||||||
* Converts a single hexadecimal digit into a decimal value.
|
* Converts a single hexadecimal digit into a decimal value.
|
||||||
*/
|
*/
|
||||||
unsigned char xsingle2c(unsigned char *what) {
|
static unsigned char xsingle2c(unsigned char *what) {
|
||||||
register unsigned char digit;
|
register unsigned char digit;
|
||||||
|
|
||||||
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
|
digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
|
||||||
@ -651,7 +655,7 @@ char *strtolower_inplace(unsigned char *str) {
|
|||||||
* Converts a single byte into its hexadecimal representation.
|
* Converts a single byte into its hexadecimal representation.
|
||||||
* Will overwrite two bytes at the destination.
|
* Will overwrite two bytes at the destination.
|
||||||
*/
|
*/
|
||||||
unsigned char *c2x(unsigned what, unsigned char *where) {
|
static unsigned char *c2x(unsigned what, unsigned char *where) {
|
||||||
static const char c2x_table[] = "0123456789abcdef";
|
static const char c2x_table[] = "0123456789abcdef";
|
||||||
|
|
||||||
what = what & 0xff;
|
what = what & 0xff;
|
||||||
@ -661,6 +665,9 @@ unsigned char *c2x(unsigned what, unsigned char *where) {
|
|||||||
return where;
|
return where;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *_log_escape(apr_pool_t *p, const unsigned char *input,
|
||||||
|
unsigned long int input_length, int escape_quotes, int escape_colon, int escape_re);
|
||||||
|
|
||||||
char *log_escape_re(apr_pool_t *mp, const char *text) {
|
char *log_escape_re(apr_pool_t *mp, const char *text) {
|
||||||
return _log_escape(mp, (const unsigned char *)text, text ? strlen(text) : 0, 1, 1, 1);
|
return _log_escape(mp, (const unsigned char *)text, text ? strlen(text) : 0, 1, 1, 1);
|
||||||
}
|
}
|
||||||
@ -681,10 +688,6 @@ char *log_escape_nq_ex(apr_pool_t *mp, const char *text, unsigned long int text_
|
|||||||
return _log_escape(mp, (const unsigned char *)text, text_length, 0, 0, 0);
|
return _log_escape(mp, (const unsigned char *)text, text_length, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *log_escape_header_name(apr_pool_t *mp, const char *text) {
|
|
||||||
return _log_escape(mp, (const unsigned char *)text, text ? strlen(text) : 0, 0, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *log_escape_raw(apr_pool_t *mp, const unsigned char *text, unsigned long int text_length) {
|
char *log_escape_raw(apr_pool_t *mp, const unsigned char *text, unsigned long int text_length) {
|
||||||
unsigned char *ret = apr_palloc(mp, text_length * 4 + 1);
|
unsigned char *ret = apr_palloc(mp, text_length * 4 + 1);
|
||||||
unsigned long int i, j;
|
unsigned long int i, j;
|
||||||
@ -751,7 +754,7 @@ char *log_escape_hex(apr_pool_t *mp, const unsigned char *text, unsigned long in
|
|||||||
/**
|
/**
|
||||||
* Transform input into a form safe for logging.
|
* Transform input into a form safe for logging.
|
||||||
*/
|
*/
|
||||||
char *_log_escape(apr_pool_t *mp, const unsigned char *input, unsigned long int input_len,
|
static char *_log_escape(apr_pool_t *mp, const unsigned char *input, unsigned long int input_len,
|
||||||
int escape_quotes, int escape_colon, int escape_re)
|
int escape_quotes, int escape_colon, int escape_re)
|
||||||
{
|
{
|
||||||
unsigned char *d = NULL;
|
unsigned char *d = NULL;
|
||||||
|
@ -51,10 +51,6 @@ int DSOLOCAL is_token_char(unsigned char c);
|
|||||||
|
|
||||||
int DSOLOCAL remove_lf_crlf_inplace(char *text);
|
int DSOLOCAL remove_lf_crlf_inplace(char *text);
|
||||||
|
|
||||||
unsigned char DSOLOCAL x2c(unsigned char *what);
|
|
||||||
|
|
||||||
unsigned char DSOLOCAL xsingle2c(unsigned char *what);
|
|
||||||
|
|
||||||
char DSOLOCAL *guess_tmp_dir(apr_pool_t *p);
|
char DSOLOCAL *guess_tmp_dir(apr_pool_t *p);
|
||||||
|
|
||||||
char DSOLOCAL *current_logtime(apr_pool_t *mp);
|
char DSOLOCAL *current_logtime(apr_pool_t *mp);
|
||||||
@ -67,8 +63,6 @@ int DSOLOCAL msc_mkstemp(char *template);
|
|||||||
|
|
||||||
char DSOLOCAL *strtolower_inplace(unsigned char *str);
|
char DSOLOCAL *strtolower_inplace(unsigned char *str);
|
||||||
|
|
||||||
unsigned char DSOLOCAL *c2x(unsigned what, unsigned char *where);
|
|
||||||
|
|
||||||
char DSOLOCAL *log_escape_re(apr_pool_t *p, const char *text);
|
char DSOLOCAL *log_escape_re(apr_pool_t *p, const char *text);
|
||||||
|
|
||||||
char DSOLOCAL *log_escape(apr_pool_t *p, const char *text);
|
char DSOLOCAL *log_escape(apr_pool_t *p, const char *text);
|
||||||
@ -79,17 +73,12 @@ char DSOLOCAL *log_escape_ex(apr_pool_t *p, const char *text, unsigned long int
|
|||||||
|
|
||||||
char DSOLOCAL *log_escape_nq_ex(apr_pool_t *p, const char *text, unsigned long int text_length);
|
char DSOLOCAL *log_escape_nq_ex(apr_pool_t *p, const char *text, unsigned long int text_length);
|
||||||
|
|
||||||
char DSOLOCAL *log_escape_header_name(apr_pool_t *p, const char *text);
|
|
||||||
|
|
||||||
char DSOLOCAL *log_escape_hex(apr_pool_t *mp, const unsigned char *text, unsigned long int text_length);
|
char DSOLOCAL *log_escape_hex(apr_pool_t *mp, const unsigned char *text, unsigned long int text_length);
|
||||||
|
|
||||||
char DSOLOCAL *log_escape_raw(apr_pool_t *mp, const unsigned char *text, unsigned long int text_length);
|
char DSOLOCAL *log_escape_raw(apr_pool_t *mp, const unsigned char *text, unsigned long int text_length);
|
||||||
|
|
||||||
char DSOLOCAL *log_escape_nul(apr_pool_t *mp, const unsigned char *text, unsigned long int text_length);
|
char DSOLOCAL *log_escape_nul(apr_pool_t *mp, const unsigned char *text, unsigned long int text_length);
|
||||||
|
|
||||||
char DSOLOCAL *_log_escape(apr_pool_t *p, const unsigned char *input,
|
|
||||||
unsigned long int input_length, int escape_quotes, int escape_colon, int escape_re);
|
|
||||||
|
|
||||||
int DSOLOCAL decode_base64_ext(char *plain_text, const char *input, int input_len);
|
int DSOLOCAL decode_base64_ext(char *plain_text, const char *input, int input_len);
|
||||||
|
|
||||||
int DSOLOCAL convert_to_int(const char c);
|
int DSOLOCAL convert_to_int(const char c);
|
||||||
|
42
apache2/re.c
42
apache2/re.c
@ -32,6 +32,15 @@ static const char *const severities[] = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static apr_status_t msre_parse_targets(msre_ruleset *ruleset, const char *text,
|
||||||
|
apr_array_header_t *arr, char **error_msg);
|
||||||
|
static char *msre_generate_target_string(apr_pool_t *pool, msre_rule *rule);
|
||||||
|
static msre_var *msre_create_var(msre_ruleset *ruleset, const char *name, const char *param,
|
||||||
|
modsec_rec *msr, char **error_msg);
|
||||||
|
static msre_action *msre_create_action(msre_engine *engine, const char *name,
|
||||||
|
const char *param, char **error_msg);
|
||||||
|
static apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr);
|
||||||
|
|
||||||
/* -- Actions, variables, functions and operator functions ----------------- */
|
/* -- Actions, variables, functions and operator functions ----------------- */
|
||||||
|
|
||||||
char *update_rule_target(cmd_parms *cmd, directory_config *dcfg,
|
char *update_rule_target(cmd_parms *cmd, directory_config *dcfg,
|
||||||
@ -197,7 +206,7 @@ static void msre_actionset_cardinality_fixup(msre_actionset *actionset, msre_act
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *msre_generate_target_string(apr_pool_t *pool, msre_rule *rule) {
|
static char *msre_generate_target_string(apr_pool_t *pool, msre_rule *rule) {
|
||||||
|
|
||||||
char *target_str = NULL;
|
char *target_str = NULL;
|
||||||
msre_var **targets = NULL;
|
msre_var **targets = NULL;
|
||||||
@ -225,7 +234,7 @@ char *msre_generate_target_string(apr_pool_t *pool, msre_rule *rule) {
|
|||||||
/**
|
/**
|
||||||
* Generate an action string from an actionset.
|
* Generate an action string from an actionset.
|
||||||
*/
|
*/
|
||||||
char *msre_actionset_generate_action_string(apr_pool_t *pool, const msre_actionset *actionset) {
|
static char *msre_actionset_generate_action_string(apr_pool_t *pool, const msre_actionset *actionset) {
|
||||||
const apr_array_header_t *tarr = NULL;
|
const apr_array_header_t *tarr = NULL;
|
||||||
const apr_table_entry_t *telts = NULL;
|
const apr_table_entry_t *telts = NULL;
|
||||||
char *actions = NULL;
|
char *actions = NULL;
|
||||||
@ -322,7 +331,7 @@ static void msre_actionset_action_add(msre_actionset *actionset, msre_action *ac
|
|||||||
* Creates msre_var instances (rule variables) out of the
|
* Creates msre_var instances (rule variables) out of the
|
||||||
* given text string and places them into the supplied table.
|
* given text string and places them into the supplied table.
|
||||||
*/
|
*/
|
||||||
apr_status_t msre_parse_targets(msre_ruleset *ruleset, const char *text,
|
static apr_status_t msre_parse_targets(msre_ruleset *ruleset, const char *text,
|
||||||
apr_array_header_t *arr, char **error_msg)
|
apr_array_header_t *arr, char **error_msg)
|
||||||
{
|
{
|
||||||
const apr_array_header_t *tarr;
|
const apr_array_header_t *tarr;
|
||||||
@ -358,7 +367,7 @@ apr_status_t msre_parse_targets(msre_ruleset *ruleset, const char *text,
|
|||||||
* Creates msre_action instances by parsing the given string, placing
|
* Creates msre_action instances by parsing the given string, placing
|
||||||
* them into the supplied array.
|
* them into the supplied array.
|
||||||
*/
|
*/
|
||||||
apr_status_t msre_parse_actions(msre_engine *engine, msre_actionset *actionset,
|
static apr_status_t msre_parse_actions(msre_engine *engine, msre_actionset *actionset,
|
||||||
const char *text, char **error_msg)
|
const char *text, char **error_msg)
|
||||||
{
|
{
|
||||||
const apr_array_header_t *tarr;
|
const apr_array_header_t *tarr;
|
||||||
@ -409,21 +418,11 @@ msre_var_metadata *msre_resolve_var(msre_engine *engine, const char *name)
|
|||||||
/**
|
/**
|
||||||
* Locates action metadata given the action name.
|
* Locates action metadata given the action name.
|
||||||
*/
|
*/
|
||||||
msre_action_metadata *msre_resolve_action(msre_engine *engine, const char *name)
|
static msre_action_metadata *msre_resolve_action(msre_engine *engine, const char *name)
|
||||||
{
|
{
|
||||||
return (msre_action_metadata *)apr_table_get(engine->actions, name);
|
return (msre_action_metadata *)apr_table_get(engine->actions, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Locates request body processor metadata given the processor name.
|
|
||||||
*/
|
|
||||||
msre_reqbody_processor_metadata *msre_resolve_reqbody_processor(
|
|
||||||
msre_engine *engine,
|
|
||||||
const char *name)
|
|
||||||
{
|
|
||||||
return (msre_reqbody_processor_metadata *)apr_table_get(engine->reqbody_processors, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new variable instance given the variable name
|
* Creates a new variable instance given the variable name
|
||||||
* and an (optional) parameter.
|
* and an (optional) parameter.
|
||||||
@ -508,7 +507,7 @@ msre_var *msre_create_var_ex(apr_pool_t *pool, msre_engine *engine, const char *
|
|||||||
* NOTE: this allocates out of the global pool and should not be used
|
* NOTE: this allocates out of the global pool and should not be used
|
||||||
* per-request
|
* per-request
|
||||||
*/
|
*/
|
||||||
msre_var *msre_create_var(msre_ruleset *ruleset, const char *name, const char *param,
|
static msre_var *msre_create_var(msre_ruleset *ruleset, const char *name, const char *param,
|
||||||
modsec_rec *msr, char **error_msg)
|
modsec_rec *msr, char **error_msg)
|
||||||
{
|
{
|
||||||
msre_var *var = msre_create_var_ex(ruleset->engine->mp, ruleset->engine, name, param, msr, error_msg);
|
msre_var *var = msre_create_var_ex(ruleset->engine->mp, ruleset->engine, name, param, msr, error_msg);
|
||||||
@ -932,15 +931,6 @@ msre_engine *msre_engine_create(apr_pool_t *parent_pool) {
|
|||||||
return engine;
|
return engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroys an engine instance, releasing the consumed memory.
|
|
||||||
*/
|
|
||||||
void msre_engine_destroy(msre_engine *engine) {
|
|
||||||
/* Destroyed automatically by the parent pool.
|
|
||||||
* apr_pool_destroy(engine->mp);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -- Recipe functions ----------------------------------------------------- */
|
/* -- Recipe functions ----------------------------------------------------- */
|
||||||
|
|
||||||
@ -2781,7 +2771,7 @@ static apr_status_t msre_rule_process_lua(msre_rule *rule, modsec_rec *msr) {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
static apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||||
/* Use a fresh memory sub-pool for processing each rule */
|
/* Use a fresh memory sub-pool for processing each rule */
|
||||||
if (msr->msc_rule_mptmp == NULL) {
|
if (msr->msc_rule_mptmp == NULL) {
|
||||||
if (apr_pool_create(&msr->msc_rule_mptmp, msr->mp) != APR_SUCCESS) {
|
if (apr_pool_create(&msr->msc_rule_mptmp, msr->mp) != APR_SUCCESS) {
|
||||||
|
26
apache2/re.h
26
apache2/re.h
@ -53,29 +53,11 @@ apr_status_t DSOLOCAL collection_original_setvar(modsec_rec *msr, const char *co
|
|||||||
|
|
||||||
int DSOLOCAL expand_macros(modsec_rec *msr, msc_string *var, msre_rule *rule, apr_pool_t *mptmp);
|
int DSOLOCAL expand_macros(modsec_rec *msr, msc_string *var, msre_rule *rule, apr_pool_t *mptmp);
|
||||||
|
|
||||||
apr_status_t DSOLOCAL msre_parse_targets(msre_ruleset *ruleset, const char *text,
|
|
||||||
apr_array_header_t *arr, char **error_msg);
|
|
||||||
|
|
||||||
apr_status_t DSOLOCAL msre_parse_actions(msre_engine *engine, msre_actionset *actionset,
|
|
||||||
const char *text, char **error_msg);
|
|
||||||
|
|
||||||
msre_var_metadata DSOLOCAL *msre_resolve_var(msre_engine *engine, const char *name);
|
msre_var_metadata DSOLOCAL *msre_resolve_var(msre_engine *engine, const char *name);
|
||||||
|
|
||||||
msre_action_metadata DSOLOCAL *msre_resolve_action(msre_engine *engine, const char *name);
|
|
||||||
|
|
||||||
msre_reqbody_processor_metadata DSOLOCAL *msre_resolve_reqbody_processor(
|
|
||||||
msre_engine *engine,
|
|
||||||
const char *name);
|
|
||||||
|
|
||||||
msre_var DSOLOCAL *msre_create_var(msre_ruleset *ruleset, const char *name, const char *param,
|
|
||||||
modsec_rec *msr, char **error_msg);
|
|
||||||
|
|
||||||
msre_var DSOLOCAL *msre_create_var_ex(apr_pool_t *pool, msre_engine *engine, const char *name, const char *param,
|
msre_var DSOLOCAL *msre_create_var_ex(apr_pool_t *pool, msre_engine *engine, const char *name, const char *param,
|
||||||
modsec_rec *msr, char **error_msg);
|
modsec_rec *msr, char **error_msg);
|
||||||
|
|
||||||
msre_action DSOLOCAL *msre_create_action(msre_engine *engine, const char *name,
|
|
||||||
const char *param, char **error_msg);
|
|
||||||
|
|
||||||
int DSOLOCAL msre_parse_generic(apr_pool_t *pool, const char *text, apr_table_t *vartable,
|
int DSOLOCAL msre_parse_generic(apr_pool_t *pool, const char *text, apr_table_t *vartable,
|
||||||
char **error_msg);
|
char **error_msg);
|
||||||
|
|
||||||
@ -84,8 +66,10 @@ int DSOLOCAL rule_id_in_range(int ruleid, const char *range);
|
|||||||
msre_var DSOLOCAL *generate_single_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
|
msre_var DSOLOCAL *generate_single_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
|
||||||
msre_rule *rule, apr_pool_t *mptmp);
|
msre_rule *rule, apr_pool_t *mptmp);
|
||||||
|
|
||||||
|
#if defined(WITH_LUA)
|
||||||
apr_table_t DSOLOCAL *generate_multi_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
|
apr_table_t DSOLOCAL *generate_multi_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
|
||||||
msre_rule *rule, apr_pool_t *mptmp);
|
msre_rule *rule, apr_pool_t *mptmp);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Structures with the corresponding functions */
|
/* Structures with the corresponding functions */
|
||||||
|
|
||||||
@ -201,8 +185,6 @@ msre_rule DSOLOCAL *msre_rule_lua_create(msre_ruleset *ruleset,
|
|||||||
const char *actions, char **error_msg);
|
const char *actions, char **error_msg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
apr_status_t DSOLOCAL msre_rule_process(msre_rule *rule, modsec_rec *msr);
|
|
||||||
|
|
||||||
#define VAR_SIMPLE 0 /* REQUEST_URI */
|
#define VAR_SIMPLE 0 /* REQUEST_URI */
|
||||||
#define VAR_LIST 1
|
#define VAR_LIST 1
|
||||||
|
|
||||||
@ -322,10 +304,6 @@ struct msre_actionset {
|
|||||||
int block;
|
int block;
|
||||||
};
|
};
|
||||||
|
|
||||||
char DSOLOCAL *msre_actionset_generate_action_string(apr_pool_t *pool, const msre_actionset *actionset);
|
|
||||||
|
|
||||||
char DSOLOCAL *msre_generate_target_string(apr_pool_t *pool, msre_rule *rule);
|
|
||||||
|
|
||||||
void DSOLOCAL msre_engine_variable_register(msre_engine *engine, const char *name,
|
void DSOLOCAL msre_engine_variable_register(msre_engine *engine, const char *name,
|
||||||
unsigned int type, unsigned int argc_min, unsigned int argc_max,
|
unsigned int type, unsigned int argc_min, unsigned int argc_max,
|
||||||
fn_var_validate_t validate, fn_var_generate_t generate,
|
fn_var_validate_t validate, fn_var_generate_t generate,
|
||||||
|
@ -101,6 +101,7 @@ msre_var *generate_single_var(modsec_rec *msr, msre_var *var, apr_array_header_t
|
|||||||
return rvar;
|
return rvar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WITH_LUA)
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -161,6 +162,7 @@ apr_table_t *generate_multi_var(modsec_rec *msr, msre_var *var, apr_array_header
|
|||||||
|
|
||||||
return tvartab;
|
return tvartab;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expands macros ("%{NAME}" entities) if present
|
* Expands macros ("%{NAME}" entities) if present
|
||||||
|
@ -92,6 +92,7 @@ static int msre_op_ipmatch_param_init(msre_rule *rule, char **error_msg) {
|
|||||||
apr_status_t rv;
|
apr_status_t rv;
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
char *saved = NULL;
|
char *saved = NULL;
|
||||||
|
char *param = NULL;
|
||||||
msre_ipmatch *current;
|
msre_ipmatch *current;
|
||||||
msre_ipmatch **last = &rule->ip_op;
|
msre_ipmatch **last = &rule->ip_op;
|
||||||
|
|
||||||
@ -100,7 +101,9 @@ static int msre_op_ipmatch_param_init(msre_rule *rule, char **error_msg) {
|
|||||||
else
|
else
|
||||||
*error_msg = NULL;
|
*error_msg = NULL;
|
||||||
|
|
||||||
str = apr_strtok( (char *)rule->op_param, "," ,&saved);
|
param = apr_pstrdup(rule->ruleset->mp, rule->op_param);
|
||||||
|
|
||||||
|
str = apr_strtok(param, ",", &saved);
|
||||||
while( str != NULL) {
|
while( str != NULL) {
|
||||||
const char *ipstr, *mask, *sep;
|
const char *ipstr, *mask, *sep;
|
||||||
|
|
||||||
@ -128,7 +131,7 @@ static int msre_op_ipmatch_param_init(msre_rule *rule, char **error_msg) {
|
|||||||
*last = current;
|
*last = current;
|
||||||
last = ¤t->next;
|
last = ¤t->next;
|
||||||
|
|
||||||
str = apr_strtok(NULL,",",&saved);
|
str = apr_strtok(NULL, ",",&saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -156,14 +159,14 @@ static int msre_op_ipmatch_execute(modsec_rec *msr, msre_rule *rule, msre_var *v
|
|||||||
*error_msg = NULL;
|
*error_msg = NULL;
|
||||||
|
|
||||||
if(current == NULL) {
|
if(current == NULL) {
|
||||||
*error_msg = "Internal Error: ipmatch value is null.";
|
msr_log(msr, 1, "ipMatch Internal Error: ipmatch value is null.");
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create an apr_sockaddr_t for the value string */
|
/* create an apr_sockaddr_t for the value string */
|
||||||
if ( apr_sockaddr_info_get(&sa, var->value, APR_UNSPEC, 0, 0, msr->mp) != APR_SUCCESS ) {
|
if ( apr_sockaddr_info_get(&sa, var->value, APR_UNSPEC, 0, 0, msr->mp) != APR_SUCCESS ) {
|
||||||
*error_msg = "Internal Error: Invalid REMOTE_ADDR address";
|
msr_log(msr, 1, "ipMatch Internal Error: Invalid ip address.");
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* look through the linked list for a match */
|
/* look through the linked list for a match */
|
||||||
@ -981,6 +984,44 @@ static int msre_op_pm_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
|||||||
|
|
||||||
/* gsbLookup */
|
/* gsbLookup */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \brief Reduce /./ to /
|
||||||
|
*
|
||||||
|
* \param pool Pointer to the memory pool
|
||||||
|
* \param domain Input data
|
||||||
|
*
|
||||||
|
* \retval domain On Failure
|
||||||
|
* \retval url On Success
|
||||||
|
*/
|
||||||
|
static const char *gsb_replace_tpath(apr_pool_t *pool, const char *domain, int len) {
|
||||||
|
|
||||||
|
char *pos = NULL, *data = NULL;
|
||||||
|
char *url = NULL;
|
||||||
|
int match = 0;
|
||||||
|
|
||||||
|
url = apr_palloc(pool, len + 1);
|
||||||
|
data = apr_palloc(pool, len + 1);
|
||||||
|
|
||||||
|
memset(data, 0, len+1);
|
||||||
|
memset(url, 0, len+1);
|
||||||
|
|
||||||
|
memcpy(url, domain, len);
|
||||||
|
|
||||||
|
while(( pos = strstr(url , "/./" )) != NULL) {
|
||||||
|
match = 1;
|
||||||
|
data[0] = '\0';
|
||||||
|
strncat(data, url, pos - url);
|
||||||
|
strcat(data , "/");
|
||||||
|
strcat(data ,pos + strlen("/./"));
|
||||||
|
strncpy(url , data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(match == 0)
|
||||||
|
return domain;
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* \brief Reduce doble dot to single dot
|
* \brief Reduce doble dot to single dot
|
||||||
*
|
*
|
||||||
@ -990,9 +1031,9 @@ static int msre_op_pm_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
|||||||
* \retval domain On Failure
|
* \retval domain On Failure
|
||||||
* \retval reduced On Success
|
* \retval reduced On Success
|
||||||
*/
|
*/
|
||||||
const char *gsb_reduce_char(modsec_rec *msr, const char *domain) {
|
static const char *gsb_reduce_char(apr_pool_t *pool, const char *domain) {
|
||||||
|
|
||||||
char *ptr = apr_pstrdup(msr->mp, domain);
|
char *ptr = apr_pstrdup(pool, domain);
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
char *reduced = NULL;
|
char *reduced = NULL;
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
@ -1001,7 +1042,7 @@ const char *gsb_reduce_char(modsec_rec *msr, const char *domain) {
|
|||||||
if(ptr == NULL)
|
if(ptr == NULL)
|
||||||
return domain;
|
return domain;
|
||||||
|
|
||||||
data = apr_pcalloc(msr->mp, strlen(ptr));
|
data = apr_pcalloc(pool, strlen(ptr));
|
||||||
|
|
||||||
if(data == NULL)
|
if(data == NULL)
|
||||||
return domain;
|
return domain;
|
||||||
@ -1155,11 +1196,11 @@ static int msre_op_gsbLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(gsb == NULL) {
|
if(gsb == NULL) {
|
||||||
*error_msg = "Internal Error: gsb database is null.";
|
msr_log(msr, 1, "GSB lookup failed without a database. Set SecGsbLookupDB.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = apr_pcalloc(msr->mp, var->value_len+1);
|
data = apr_pcalloc(rule->ruleset->mp, var->value_len+1);
|
||||||
|
|
||||||
if(data == NULL) {
|
if(data == NULL) {
|
||||||
*error_msg = "Internal Error: cannot allocate memory for data.";
|
*error_msg = "Internal Error: cannot allocate memory for data.";
|
||||||
@ -1174,16 +1215,18 @@ static int msre_op_gsbLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
|||||||
{
|
{
|
||||||
for(i = 0; i < rv; ++i)
|
for(i = 0; i < rv; ++i)
|
||||||
{
|
{
|
||||||
match = apr_psprintf(msr->mp, "%.*s", ovector[2*i+1] - ovector[2*i], data + ovector[2*i]);
|
match = apr_psprintf(rule->ruleset->mp, "%.*s", ovector[2*i+1] - ovector[2*i], data + ovector[2*i]);
|
||||||
|
|
||||||
if (match == NULL) {
|
if (match == NULL) {
|
||||||
*error_msg = "Internal Error: cannot allocate memory for match.";
|
*error_msg = "Internal Error: cannot allocate memory for match.";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
match = remove_escape(msr->mp, match, strlen(match));
|
match = remove_escape(rule->ruleset->mp, match, strlen(match));
|
||||||
|
|
||||||
match = gsb_reduce_char(msr, match);
|
match = gsb_replace_tpath(rule->ruleset->mp, match, strlen(match));
|
||||||
|
|
||||||
|
match = gsb_reduce_char(rule->ruleset->mp, match);
|
||||||
|
|
||||||
match_length = strlen(match);
|
match_length = strlen(match);
|
||||||
|
|
||||||
|
@ -1487,7 +1487,7 @@ static int var_outbound_error_generate(modsec_rec *msr, msre_var *var, msre_rule
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apr_time_t calculate_perf_combined(modsec_rec *msr) {
|
static apr_time_t calculate_perf_combined(modsec_rec *msr) {
|
||||||
return msr->time_phase1 + msr->time_phase2 + msr->time_phase3 + msr->time_phase4
|
return msr->time_phase1 + msr->time_phase2 + msr->time_phase3 + msr->time_phase4
|
||||||
+ msr->time_phase5 + msr->time_storage_write /* time_storage_read is already
|
+ msr->time_phase5 + msr->time_storage_write /* time_storage_read is already
|
||||||
included in phases */ + msr->time_logging + msr->time_gc;
|
included in phases */ + msr->time_logging + msr->time_gc;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user