diff --git a/apache2/acmp.c b/apache2/acmp.c index a00f1f64..5f55b8e1 100644 --- a/apache2/acmp.c +++ b/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; } -/** - * 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) { acmp_btree_node_t *bnode = node->btree; for (;;) { @@ -465,29 +438,6 @@ static apr_status_t acmp_connect_fail_branches(ACMP *parser) { 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; } -/** - * 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 */ @@ -642,122 +550,6 @@ apr_status_t acmp_add_pattern(ACMP *parser, const char *pattern, 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 */ diff --git a/apache2/apache2.h b/apache2/apache2.h index 48918060..dfb2a96a 100644 --- a/apache2/apache2.h +++ b/apache2/apache2.h @@ -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); -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_error(modsec_rec *msr, const char *text, ...) PRINTF_ATTRIBUTE(2,3); diff --git a/apache2/apache2_util.c b/apache2/apache2_util.c index eb345b19..219fbac1 100644 --- a/apache2/apache2_util.c +++ b/apache2/apache2_util.c @@ -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 * 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) { apr_size_t nbytes, nbytes_written; @@ -279,15 +279,6 @@ void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *msr, 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 * Apache error log if the message is important enough. diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c index 9b2ff120..b41f6c5b 100644 --- a/apache2/mod_security2.c +++ b/apache2/mod_security2.c @@ -41,11 +41,9 @@ msc_engine DSOLOCAL *modsecurity = NULL; char DSOLOCAL *chroot_dir = NULL; -unsigned int DSOLOCAL chroot_completed = 0; - char DSOLOCAL *new_server_signature = NULL; -char DSOLOCAL *real_server_signature = NULL; +static char *real_server_signature = NULL; char DSOLOCAL *guardianlog_name = NULL; @@ -73,7 +71,7 @@ typedef struct { * * \param mp Pointer to memory pool */ -void version(apr_pool_t *mp) { +static void version(apr_pool_t *mp) { char *pcre_vrs = 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); } - chroot_completed = 1; - ap_log_error(APLOG_MARK, APLOG_NOTICE | APLOG_NOERRNO, 0, s, "ModSecurity: chroot successful, path=%s", chroot_dir); } else { @@ -1297,19 +1293,19 @@ static void modsec_register_reqbody_processor(const char *name, * Registers module hooks with Apache. */ 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_ssl.c", NULL }; - static const char *postconfig_afterme_list[] = { + static const char *const postconfig_afterme_list[] = { "mod_fcgid.c", "mod_cgid.c", NULL }; - static const char *postread_beforeme_list[] = { + static const char *const postread_beforeme_list[] = { "mod_rpaf.c", "mod_rpaf-2.0.c", "mod_extract_forwarded2.c", @@ -1321,12 +1317,12 @@ static void register_hooks(apr_pool_t *mp) { NULL }; - static const char *postread_afterme_list[] = { + static const char *const postread_afterme_list[] = { "mod_log_forensic.c", NULL }; - static const char *transaction_afterme_list[] = { + static const char *const transaction_afterme_list[] = { "mod_log_config.c", NULL }; diff --git a/apache2/modsecurity.h b/apache2/modsecurity.h index 18795488..25472aaf 100644 --- a/apache2/modsecurity.h +++ b/apache2/modsecurity.h @@ -122,7 +122,6 @@ typedef struct msc_parm msc_parm; #define FATAL_ERROR "ModSecurity: Fatal error (memory allocation or unexpected internal error)!" extern DSOLOCAL char *new_server_signature; -extern DSOLOCAL char *real_server_signature; extern DSOLOCAL char *chroot_dir; extern module AP_MODULE_DECLARE_DATA security2_module; diff --git a/apache2/msc_geo.c b/apache2/msc_geo.c index fa0f4377..1ebf4d65 100644 --- a/apache2/msc_geo.c +++ b/apache2/msc_geo.c @@ -152,7 +152,6 @@ static void create_segments(geo_db *geo) { unsigned char delim[3]; unsigned char buf[GEO_SEGMENT_RECORD_LENGTH]; apr_size_t nbytes; - apr_status_t rc; apr_off_t offset; 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++) { - 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) { - 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) { geo->dbtype -= 105; } @@ -181,7 +180,7 @@ static void create_segments(geo_db *geo) { geo->dbtype == GEOIP_ISP_EDITION || geo->dbtype == GEOIP_ASNUM_EDITION) { 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++) { 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; } -/** - * Frees the resources used for Geo lookups - */ -apr_status_t geo_cleanup(modsec_rec *msr) -{ - return APR_SUCCESS; -} - diff --git a/apache2/msc_geo.h b/apache2/msc_geo.h index 7b7dc466..8b64cb0d 100644 --- a/apache2/msc_geo.h +++ b/apache2/msc_geo.h @@ -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); -apr_status_t DSOLOCAL geo_cleanup(modsec_rec *msr); - #endif diff --git a/apache2/msc_logging.c b/apache2/msc_logging.c index eb02cc51..b78e5e3a 100644 --- a/apache2/msc_logging.c +++ b/apache2/msc_logging.c @@ -68,51 +68,6 @@ static int sec_auditlog_write(modsec_rec *msr, const char *data, unsigned int le 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 * 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 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; msre_rule **rules = 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 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; 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++) { if (parts[cfiles]->type == MULTIPART_FILE) { 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 : "")); + 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 : "")); sec_auditlog_write(msr, text, strlen(text)); 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)); } diff --git a/apache2/msc_logging.h b/apache2/msc_logging.h index fcd70b25..308b09b6 100644 --- a/apache2/msc_logging.h +++ b/apache2/msc_logging.h @@ -42,8 +42,6 @@ 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); void DSOLOCAL sec_audit_logger(modsec_rec *msr); diff --git a/apache2/msc_pcre.c b/apache2/msc_pcre.c index 5b92b7fc..2faaf590 100644 --- a/apache2/msc_pcre.c +++ b/apache2/msc_pcre.c @@ -18,7 +18,7 @@ /** * 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->pe != NULL) { free(regex->pe); diff --git a/apache2/msc_pcre.h b/apache2/msc_pcre.h index 4891f61c..af581332 100644 --- a/apache2/msc_pcre.h +++ b/apache2/msc_pcre.h @@ -38,8 +38,6 @@ struct msc_regex_t { 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, const char **_errptr, int *_erroffset, int match_limit, int match_limit_recursion); diff --git a/apache2/msc_release.c b/apache2/msc_release.c index 6d4c350d..291c756b 100644 --- a/apache2/msc_release.c +++ b/apache2/msc_release.c @@ -14,20 +14,22 @@ #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 */ { "-rc", 3 }, /* Release Candidate build */ { "", 9 }, /* Production build */ { "-tw", 9 }, /* Truswave Holdings build */ - { "-trunk", 9 }, /* Trunk build */ - { NULL, -1 } /* terminator */ + { "-trunk", 9 } /* Trunk build */ }; 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) { return modsec_build_type[i].val; } diff --git a/apache2/msc_release.h b/apache2/msc_release.h index 1d4448b8..3ced60cc 100644 --- a/apache2/msc_release.h +++ b/apache2/msc_release.h @@ -36,17 +36,11 @@ #define PRINTF_ATTRIBUTE(a,b) #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_MINOR "6" #define MODSEC_VERSION_MAINT "0" #define MODSEC_VERSION_TYPE "-rc" -#define MODSEC_VERSION_RELEASE "1" +#define MODSEC_VERSION_RELEASE "2" #define MODSEC_VERSION_SUFFIX MODSEC_VERSION_TYPE MODSEC_VERSION_RELEASE diff --git a/apache2/msc_util.c b/apache2/msc_util.c index 6c67c1b7..53ff7369 100644 --- a/apache2/msc_util.c +++ b/apache2/msc_util.c @@ -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 }; +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 * * \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 * but does not check for overflows. */ -unsigned char x2c(unsigned char *what) { +static unsigned char x2c(unsigned char *what) { register unsigned char digit; 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. */ -unsigned char xsingle2c(unsigned char *what) { +static unsigned char xsingle2c(unsigned char *what) { register unsigned char digit; 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. * 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"; what = what & 0xff; @@ -661,6 +665,9 @@ unsigned char *c2x(unsigned what, unsigned char *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) { 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); } -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) { unsigned char *ret = apr_palloc(mp, text_length * 4 + 1); 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. */ -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) { unsigned char *d = NULL; diff --git a/apache2/msc_util.h b/apache2/msc_util.h index f088794b..8617478c 100644 --- a/apache2/msc_util.h +++ b/apache2/msc_util.h @@ -51,10 +51,6 @@ int DSOLOCAL is_token_char(unsigned char c); 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 *current_logtime(apr_pool_t *mp); @@ -67,8 +63,6 @@ int DSOLOCAL msc_mkstemp(char *template); 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(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_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_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(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 convert_to_int(const char c); diff --git a/apache2/re.c b/apache2/re.c index ea85709a..2c527eab 100644 --- a/apache2/re.c +++ b/apache2/re.c @@ -32,6 +32,15 @@ static const char *const severities[] = { 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 ----------------- */ 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; 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. */ -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_table_entry_t *telts = 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 * 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) { 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 * 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 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. */ -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); } -/** - * 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 * 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 * 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) { 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; } -/** - * 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 ----------------------------------------------------- */ @@ -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 */ if (msr->msc_rule_mptmp == NULL) { if (apr_pool_create(&msr->msc_rule_mptmp, msr->mp) != APR_SUCCESS) { diff --git a/apache2/re.h b/apache2/re.h index 6566782c..b36dd244 100644 --- a/apache2/re.h +++ b/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); -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_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, 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, 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_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, msre_rule *rule, apr_pool_t *mptmp); +#endif /* 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); #endif -apr_status_t DSOLOCAL msre_rule_process(msre_rule *rule, modsec_rec *msr); - #define VAR_SIMPLE 0 /* REQUEST_URI */ #define VAR_LIST 1 @@ -322,10 +304,6 @@ struct msre_actionset { 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, unsigned int type, unsigned int argc_min, unsigned int argc_max, fn_var_validate_t validate, fn_var_generate_t generate, diff --git a/apache2/re_actions.c b/apache2/re_actions.c index 99cc60c1..eed9f82c 100644 --- a/apache2/re_actions.c +++ b/apache2/re_actions.c @@ -101,6 +101,7 @@ msre_var *generate_single_var(modsec_rec *msr, msre_var *var, apr_array_header_t 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; } +#endif /** * Expands macros ("%{NAME}" entities) if present diff --git a/apache2/re_operators.c b/apache2/re_operators.c index 2d8c51ef..513ceae8 100644 --- a/apache2/re_operators.c +++ b/apache2/re_operators.c @@ -92,6 +92,7 @@ static int msre_op_ipmatch_param_init(msre_rule *rule, char **error_msg) { apr_status_t rv; char *str = NULL; char *saved = NULL; + char *param = NULL; msre_ipmatch *current; msre_ipmatch **last = &rule->ip_op; @@ -100,7 +101,9 @@ static int msre_op_ipmatch_param_init(msre_rule *rule, char **error_msg) { else *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) { 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 = ¤t->next; - str = apr_strtok(NULL,",",&saved); + str = apr_strtok(NULL, ",",&saved); } return 1; @@ -156,14 +159,14 @@ static int msre_op_ipmatch_execute(modsec_rec *msr, msre_rule *rule, msre_var *v *error_msg = NULL; if(current == NULL) { - *error_msg = "Internal Error: ipmatch value is null."; - return -1; + msr_log(msr, 1, "ipMatch Internal Error: ipmatch value is null."); + return 0; } /* 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 ) { - *error_msg = "Internal Error: Invalid REMOTE_ADDR address"; - return -1; + msr_log(msr, 1, "ipMatch Internal Error: Invalid ip address."); + return 0; } /* 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 */ +/* + * \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 * @@ -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 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 *reduced = NULL; int skip = 0; @@ -1001,7 +1042,7 @@ const char *gsb_reduce_char(modsec_rec *msr, const char *domain) { if(ptr == NULL) return domain; - data = apr_pcalloc(msr->mp, strlen(ptr)); + data = apr_pcalloc(pool, strlen(ptr)); if(data == NULL) return domain; @@ -1155,11 +1196,11 @@ static int msre_op_gsbLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var } 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; } - data = apr_pcalloc(msr->mp, var->value_len+1); + data = apr_pcalloc(rule->ruleset->mp, var->value_len+1); if(data == NULL) { *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) { - 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) { *error_msg = "Internal Error: cannot allocate memory for match."; 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); diff --git a/apache2/re_variables.c b/apache2/re_variables.c index e81ec644..fd7af58b 100644 --- a/apache2/re_variables.c +++ b/apache2/re_variables.c @@ -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 + msr->time_phase5 + msr->time_storage_write /* time_storage_read is already included in phases */ + msr->time_logging + msr->time_gc;