/lib/modsecurity-apache_2.6.1/apache2/apache2_config.c
C | 2656 lines | 1961 code | 459 blank | 236 comment | 607 complexity | 352f7e69bbf4a663c7588539ba0ab021 MD5 | raw file
Possible License(s): Apache-2.0
Large files files are truncated, but you can click here to view the full file
- /*
- * ModSecurity for Apache 2.x, http://www.modsecurity.org/
- * Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/)
- *
- * You may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * If any of the files related to licensing are missing or if you have any
- * other questions related to licensing please contact Trustwave Holdings, Inc.
- * directly using the email address security@modsecurity.org.
- */
- #include <limits.h>
- #include "modsecurity.h"
- #include "msc_logging.h"
- #include "msc_util.h"
- #include "http_log.h"
- #if defined(WITH_LUA)
- #include "msc_lua.h"
- #endif
- /* -- Directory context creation and initialisation -- */
- /**
- * Creates a fresh directory configuration.
- */
- void *create_directory_config(apr_pool_t *mp, char *path)
- {
- directory_config *dcfg = (directory_config *)apr_pcalloc(mp, sizeof(directory_config));
- if (dcfg == NULL) return NULL;
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Created directory config %pp path %s", dcfg, path);
- #endif
- dcfg->mp = mp;
- dcfg->is_enabled = NOT_SET;
- dcfg->reqbody_access = NOT_SET;
- dcfg->reqintercept_oe = NOT_SET;
- dcfg->reqbody_buffering = NOT_SET;
- dcfg->reqbody_inmemory_limit = NOT_SET;
- dcfg->reqbody_limit = NOT_SET;
- dcfg->reqbody_no_files_limit = NOT_SET;
- dcfg->resbody_access = NOT_SET;
- dcfg->debuglog_name = NOT_SET_P;
- dcfg->debuglog_level = NOT_SET;
- dcfg->debuglog_fd = NOT_SET_P;
- dcfg->of_limit = NOT_SET;
- dcfg->if_limit_action = NOT_SET;
- dcfg->of_limit_action = NOT_SET;
- dcfg->of_mime_types = NOT_SET_P;
- dcfg->of_mime_types_cleared = NOT_SET;
- dcfg->cookie_format = NOT_SET;
- dcfg->argument_separator = NOT_SET;
- dcfg->rule_inheritance = NOT_SET;
- dcfg->rule_exceptions = apr_array_make(mp, 16, sizeof(rule_exception *));
- /* audit log variables */
- dcfg->auditlog_flag = NOT_SET;
- dcfg->auditlog_type = NOT_SET;
- dcfg->auditlog_dirperms = NOT_SET;
- dcfg->auditlog_fileperms = NOT_SET;
- dcfg->auditlog_name = NOT_SET_P;
- dcfg->auditlog2_name = NOT_SET_P;
- dcfg->auditlog_fd = NOT_SET_P;
- dcfg->auditlog2_fd = NOT_SET_P;
- dcfg->auditlog_storage_dir = NOT_SET_P;
- dcfg->auditlog_parts = NOT_SET_P;
- dcfg->auditlog_relevant_regex = NOT_SET_P;
- dcfg->ruleset = NULL;
- /* Upload */
- dcfg->tmp_dir = NOT_SET_P;
- dcfg->upload_dir = NOT_SET_P;
- dcfg->upload_keep_files = NOT_SET;
- dcfg->upload_validates_files = NOT_SET;
- dcfg->upload_filemode = NOT_SET;
- dcfg->upload_file_limit = NOT_SET;
- /* These are only used during the configuration process. */
- dcfg->tmp_chain_starter = NULL;
- dcfg->tmp_default_actionset = NULL;
- dcfg->tmp_rule_placeholders = NULL;
- /* Misc */
- dcfg->data_dir = NOT_SET_P;
- dcfg->webappid = NOT_SET_P;
- /* Content injection. */
- dcfg->content_injection_enabled = NOT_SET;
- /* Stream inspection */
- dcfg->stream_inbody_inspection = NOT_SET;
- dcfg->stream_outbody_inspection = NOT_SET;
- /* Geo Lookups */
- dcfg->geo = NOT_SET_P;
- /* Gsb Lookups */
- dcfg->gsb = NOT_SET_P;
- /* Unicode Map */
- dcfg->u_map = NOT_SET_P;
- /* Cache */
- dcfg->cache_trans = NOT_SET;
- dcfg->cache_trans_incremental = NOT_SET;
- dcfg->cache_trans_min = NOT_SET;
- dcfg->cache_trans_max = NOT_SET;
- dcfg->cache_trans_maxitems = NOT_SET;
- dcfg->component_signatures = apr_array_make(mp, 16, sizeof(char *));
- dcfg->request_encoding = NOT_SET_P;
- dcfg->disable_backend_compression = NOT_SET;
- return dcfg;
- }
- /**
- * Copies rules between one phase of two configuration contexts,
- * taking exceptions into account.
- */
- static void copy_rules_phase(apr_pool_t *mp,
- apr_array_header_t *parent_phase_arr,
- apr_array_header_t *child_phase_arr,
- apr_array_header_t *exceptions_arr)
- {
- rule_exception **exceptions;
- msre_rule **rules;
- int i, j;
- int mode = 0;
- rules = (msre_rule **)parent_phase_arr->elts;
- for(i = 0; i < parent_phase_arr->nelts; i++) {
- msre_rule *rule = (msre_rule *)rules[i];
- int copy = 1;
- if (mode == 0) {
- /* First rule in the chain. */
- exceptions = (rule_exception **)exceptions_arr->elts;
- for(j = 0; j < exceptions_arr->nelts; j++) {
- /* Process exceptions. */
- switch(exceptions[j]->type) {
- case RULE_EXCEPTION_REMOVE_ID :
- if ((rule->actionset != NULL)&&(rule->actionset->id != NULL)) {
- int ruleid = atoi(rule->actionset->id);
- if (rule_id_in_range(ruleid, exceptions[j]->param)) copy--;
- }
- break;
- case RULE_EXCEPTION_REMOVE_MSG :
- if ((rule->actionset != NULL)&&(rule->actionset->msg != NULL)) {
- char *my_error_msg = NULL;
- int rc = msc_regexec(exceptions[j]->param_data,
- rule->actionset->msg, strlen(rule->actionset->msg),
- &my_error_msg);
- if (rc >= 0) copy--;
- }
- break;
- case RULE_EXCEPTION_REMOVE_TAG :
- if ((rule->actionset != NULL)&&(apr_is_empty_table(rule->actionset->actions) == 0)) {
- char *my_error_msg = NULL;
- const apr_array_header_t *tarr = NULL;
- const apr_table_entry_t *telts = NULL;
- int c;
- tarr = apr_table_elts(rule->actionset->actions);
- telts = (const apr_table_entry_t*)tarr->elts;
- for (c = 0; c < tarr->nelts; c++) {
- msre_action *action = (msre_action *)telts[c].val;
- if(strcmp("tag", action->metadata->name) == 0) {
- int rc = msc_regexec(exceptions[j]->param_data,
- action->param, strlen(action->param),
- &my_error_msg);
- if (rc >= 0) copy--;
- }
- }
- }
- break;
- }
- }
- if (copy > 0) {
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Copy rule %pp [id \"%s\"]", rule, rule->actionset->id);
- #endif
- /* Copy the rule. */
- *(msre_rule **)apr_array_push(child_phase_arr) = rule;
- if (rule->actionset->is_chained) mode = 2;
- } else {
- if (rule->actionset->is_chained) mode = 1;
- }
- } else {
- if (mode == 2) {
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Copy chain %pp for rule %pp [id \"%s\"]", rule, rule->chain_starter, rule->chain_starter->actionset->id);
- #endif
- /* Copy the rule (it belongs to the chain we want to include. */
- *(msre_rule **)apr_array_push(child_phase_arr) = rule;
- }
- if ((rule->actionset == NULL)||(rule->actionset->is_chained == 0)) mode = 0;
- }
- }
- }
- /**
- * Copies rules between two configuration contexts,
- * taking exceptions into account.
- */
- static int copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset,
- msre_ruleset *child_ruleset,
- apr_array_header_t *exceptions_arr)
- {
- copy_rules_phase(mp, parent_ruleset->phase_request_headers,
- child_ruleset->phase_request_headers, exceptions_arr);
- copy_rules_phase(mp, parent_ruleset->phase_request_body,
- child_ruleset->phase_request_body, exceptions_arr);
- copy_rules_phase(mp, parent_ruleset->phase_response_headers,
- child_ruleset->phase_response_headers, exceptions_arr);
- copy_rules_phase(mp, parent_ruleset->phase_response_body,
- child_ruleset->phase_response_body, exceptions_arr);
- copy_rules_phase(mp, parent_ruleset->phase_logging,
- child_ruleset->phase_logging, exceptions_arr);
- return 1;
- }
- /**
- * Merges two directory configurations.
- */
- void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
- {
- directory_config *parent = (directory_config *)_parent;
- directory_config *child = (directory_config *)_child;
- directory_config *merged = create_directory_config(mp, NULL);
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Merge parent %pp child %pp RESULT %pp", _parent, _child, merged);
- #endif
- if (merged == NULL) return NULL;
- /* Use values from the child configuration where possible,
- * otherwise use the parent's.
- */
- merged->is_enabled = (child->is_enabled == NOT_SET
- ? parent->is_enabled : child->is_enabled);
- /* IO parameters */
- merged->reqbody_access = (child->reqbody_access == NOT_SET
- ? parent->reqbody_access : child->reqbody_access);
- merged->reqbody_buffering = (child->reqbody_buffering == NOT_SET
- ? parent->reqbody_buffering : child->reqbody_buffering);
- merged->reqbody_inmemory_limit = (child->reqbody_inmemory_limit == NOT_SET
- ? parent->reqbody_inmemory_limit : child->reqbody_inmemory_limit);
- merged->reqbody_limit = (child->reqbody_limit == NOT_SET
- ? parent->reqbody_limit : child->reqbody_limit);
- merged->reqbody_no_files_limit = (child->reqbody_no_files_limit == NOT_SET
- ? parent->reqbody_no_files_limit : child->reqbody_no_files_limit);
- merged->resbody_access = (child->resbody_access == NOT_SET
- ? parent->resbody_access : child->resbody_access);
- merged->of_limit = (child->of_limit == NOT_SET
- ? parent->of_limit : child->of_limit);
- merged->if_limit_action = (child->if_limit_action == NOT_SET
- ? parent->if_limit_action : child->if_limit_action);
- merged->of_limit_action = (child->of_limit_action == NOT_SET
- ? parent->of_limit_action : child->of_limit_action);
- merged->reqintercept_oe = (child->reqintercept_oe == NOT_SET
- ? parent->reqintercept_oe : child->reqintercept_oe);
- if (child->of_mime_types != NOT_SET_P) {
- /* Child added to the table */
- if (child->of_mime_types_cleared == 1) {
- /* The list of MIME types was cleared in the child,
- * which means the parent's MIME types went away and
- * we should not take them into consideration here.
- */
- merged->of_mime_types = child->of_mime_types;
- merged->of_mime_types_cleared = 1;
- } else {
- /* Add MIME types defined in the child to those
- * defined in the parent context.
- */
- if (parent->of_mime_types == NOT_SET_P) {
- merged->of_mime_types = child->of_mime_types;
- merged->of_mime_types_cleared = NOT_SET;
- } else {
- merged->of_mime_types = apr_table_overlay(mp, parent->of_mime_types,
- child->of_mime_types);
- if (merged->of_mime_types == NULL) return NULL;
- }
- }
- } else {
- /* Child did not add to the table */
- if (child->of_mime_types_cleared == 1) {
- merged->of_mime_types_cleared = 1;
- } else {
- merged->of_mime_types = parent->of_mime_types;
- merged->of_mime_types_cleared = parent->of_mime_types_cleared;
- }
- }
- /* debug log */
- if (child->debuglog_fd == NOT_SET_P) {
- merged->debuglog_name = parent->debuglog_name;
- merged->debuglog_fd = parent->debuglog_fd;
- } else {
- merged->debuglog_name = child->debuglog_name;
- merged->debuglog_fd = child->debuglog_fd;
- }
- merged->debuglog_level = (child->debuglog_level == NOT_SET
- ? parent->debuglog_level : child->debuglog_level);
- merged->cookie_format = (child->cookie_format == NOT_SET
- ? parent->cookie_format : child->cookie_format);
- merged->argument_separator = (child->argument_separator == NOT_SET
- ? parent->argument_separator : child->argument_separator);
- /* rule inheritance */
- if ((child->rule_inheritance == NOT_SET)||(child->rule_inheritance == 1)) {
- merged->rule_inheritance = parent->rule_inheritance;
- if ((child->ruleset == NULL)&&(parent->ruleset == NULL)) {
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "No rules in this context.");
- #endif
- /* Do nothing, there are no rules in either context. */
- } else
- if (child->ruleset == NULL) {
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Using parent rules in this context.");
- #endif
- /* Copy the rules from the parent context. */
- merged->ruleset = msre_ruleset_create(parent->ruleset->engine, mp);
- copy_rules(mp, parent->ruleset, merged->ruleset, child->rule_exceptions);
- } else
- if (parent->ruleset == NULL) {
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Using child rules in this context.");
- #endif
- /* Copy child rules. */
- merged->ruleset = msre_ruleset_create(child->ruleset->engine, mp);
- merged->ruleset->phase_request_headers = apr_array_copy(mp,
- child->ruleset->phase_request_headers);
- merged->ruleset->phase_request_body = apr_array_copy(mp,
- child->ruleset->phase_request_body);
- merged->ruleset->phase_response_headers = apr_array_copy(mp,
- child->ruleset->phase_response_headers);
- merged->ruleset->phase_response_body = apr_array_copy(mp,
- child->ruleset->phase_response_body);
- merged->ruleset->phase_logging = apr_array_copy(mp,
- child->ruleset->phase_logging);
- } else {
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Using parent then child rules in this context.");
- #endif
- /* Copy parent rules, then add child rules to it. */
- merged->ruleset = msre_ruleset_create(parent->ruleset->engine, mp);
- copy_rules(mp, parent->ruleset, merged->ruleset, child->rule_exceptions);
- apr_array_cat(merged->ruleset->phase_request_headers,
- child->ruleset->phase_request_headers);
- apr_array_cat(merged->ruleset->phase_request_body,
- child->ruleset->phase_request_body);
- apr_array_cat(merged->ruleset->phase_response_headers,
- child->ruleset->phase_response_headers);
- apr_array_cat(merged->ruleset->phase_response_body,
- child->ruleset->phase_response_body);
- apr_array_cat(merged->ruleset->phase_logging,
- child->ruleset->phase_logging);
- }
- } else {
- merged->rule_inheritance = 0;
- if (child->ruleset != NULL) {
- /* Copy child rules. */
- merged->ruleset = msre_ruleset_create(child->ruleset->engine, mp);
- merged->ruleset->phase_request_headers = apr_array_copy(mp,
- child->ruleset->phase_request_headers);
- merged->ruleset->phase_request_body = apr_array_copy(mp,
- child->ruleset->phase_request_body);
- merged->ruleset->phase_response_headers = apr_array_copy(mp,
- child->ruleset->phase_response_headers);
- merged->ruleset->phase_response_body = apr_array_copy(mp,
- child->ruleset->phase_response_body);
- merged->ruleset->phase_logging = apr_array_copy(mp,
- child->ruleset->phase_logging);
- }
- }
- /* Merge rule exceptions. */
- merged->rule_exceptions = apr_array_append(mp, parent->rule_exceptions,
- child->rule_exceptions);
- /* audit log variables */
- merged->auditlog_flag = (child->auditlog_flag == NOT_SET
- ? parent->auditlog_flag : child->auditlog_flag);
- merged->auditlog_type = (child->auditlog_type == NOT_SET
- ? parent->auditlog_type : child->auditlog_type);
- merged->auditlog_dirperms = (child->auditlog_dirperms == NOT_SET
- ? parent->auditlog_dirperms : child->auditlog_dirperms);
- merged->auditlog_fileperms = (child->auditlog_fileperms == NOT_SET
- ? parent->auditlog_fileperms : child->auditlog_fileperms);
- if (child->auditlog_fd != NOT_SET_P) {
- merged->auditlog_fd = child->auditlog_fd;
- merged->auditlog_name = child->auditlog_name;
- } else {
- merged->auditlog_fd = parent->auditlog_fd;
- merged->auditlog_name = parent->auditlog_name;
- }
- if (child->auditlog2_fd != NOT_SET_P) {
- merged->auditlog2_fd = child->auditlog2_fd;
- merged->auditlog2_name = child->auditlog2_name;
- } else {
- merged->auditlog2_fd = parent->auditlog2_fd;
- merged->auditlog2_name = parent->auditlog2_name;
- }
- merged->auditlog_storage_dir = (child->auditlog_storage_dir == NOT_SET_P
- ? parent->auditlog_storage_dir : child->auditlog_storage_dir);
- merged->auditlog_parts = (child->auditlog_parts == NOT_SET_P
- ? parent->auditlog_parts : child->auditlog_parts);
- merged->auditlog_relevant_regex = (child->auditlog_relevant_regex == NOT_SET_P
- ? parent->auditlog_relevant_regex : child->auditlog_relevant_regex);
- /* Upload */
- merged->tmp_dir = (child->tmp_dir == NOT_SET_P
- ? parent->tmp_dir : child->tmp_dir);
- merged->upload_dir = (child->upload_dir == NOT_SET_P
- ? parent->upload_dir : child->upload_dir);
- merged->upload_keep_files = (child->upload_keep_files == NOT_SET
- ? parent->upload_keep_files : child->upload_keep_files);
- merged->upload_validates_files = (child->upload_validates_files == NOT_SET
- ? parent->upload_validates_files : child->upload_validates_files);
- merged->upload_filemode = (child->upload_filemode == NOT_SET
- ? parent->upload_filemode : child->upload_filemode);
- merged->upload_file_limit = (child->upload_file_limit == NOT_SET
- ? parent->upload_file_limit : child->upload_file_limit);
- /* Misc */
- merged->data_dir = (child->data_dir == NOT_SET_P
- ? parent->data_dir : child->data_dir);
- merged->webappid = (child->webappid == NOT_SET_P
- ? parent->webappid : child->webappid);
- /* Content injection. */
- merged->content_injection_enabled = (child->content_injection_enabled == NOT_SET
- ? parent->content_injection_enabled : child->content_injection_enabled);
- /* Stream inspection */
- merged->stream_inbody_inspection = (child->stream_inbody_inspection == NOT_SET
- ? parent->stream_inbody_inspection : child->stream_inbody_inspection);
- merged->stream_outbody_inspection = (child->stream_outbody_inspection == NOT_SET
- ? parent->stream_outbody_inspection : child->stream_outbody_inspection);
- /* Geo Lookup */
- merged->geo = (child->geo == NOT_SET_P
- ? parent->geo : child->geo);
- /* Gsb Lookup */
- merged->gsb = (child->gsb == NOT_SET_P
- ? parent->gsb : child->gsb);
- /* Unicode Map */
- merged->u_map = (child->u_map == NOT_SET_P
- ? parent->u_map : child->u_map);
- /* Cache */
- merged->cache_trans = (child->cache_trans == NOT_SET
- ? parent->cache_trans : child->cache_trans);
- merged->cache_trans_incremental = (child->cache_trans_incremental == NOT_SET
- ? parent->cache_trans_incremental : child->cache_trans_incremental);
- merged->cache_trans_min = (child->cache_trans_min == (apr_size_t)NOT_SET
- ? parent->cache_trans_min : child->cache_trans_min);
- merged->cache_trans_max = (child->cache_trans_max == (apr_size_t)NOT_SET
- ? parent->cache_trans_max : child->cache_trans_max);
- merged->cache_trans_maxitems = (child->cache_trans_maxitems == (apr_size_t)NOT_SET
- ? parent->cache_trans_maxitems : child->cache_trans_maxitems);
- /* Merge component signatures. */
- merged->component_signatures = apr_array_append(mp, parent->component_signatures,
- child->component_signatures);
- merged->request_encoding = (child->request_encoding == NOT_SET_P
- ? parent->request_encoding : child->request_encoding);
- merged->disable_backend_compression = (child->disable_backend_compression == NOT_SET
- ? parent->disable_backend_compression : child->disable_backend_compression);
- return merged;
- }
- /**
- * Initialise directory configuration. This function is *not* meant
- * to be called for directory configuration instances created during
- * the configuration phase. It can only be called on copies of those
- * (created fresh for every transaction).
- */
- void init_directory_config(directory_config *dcfg)
- {
- if (dcfg == NULL) return;
- if (dcfg->is_enabled == NOT_SET) dcfg->is_enabled = 0;
- if (dcfg->reqbody_access == NOT_SET) dcfg->reqbody_access = 0;
- if (dcfg->reqintercept_oe == NOT_SET) dcfg->reqintercept_oe = 0;
- if (dcfg->reqbody_buffering == NOT_SET) dcfg->reqbody_buffering = REQUEST_BODY_FORCEBUF_OFF;
- if (dcfg->reqbody_inmemory_limit == NOT_SET)
- dcfg->reqbody_inmemory_limit = REQUEST_BODY_DEFAULT_INMEMORY_LIMIT;
- if (dcfg->reqbody_limit == NOT_SET) dcfg->reqbody_limit = REQUEST_BODY_DEFAULT_LIMIT;
- if (dcfg->reqbody_no_files_limit == NOT_SET) dcfg->reqbody_no_files_limit = REQUEST_BODY_NO_FILES_DEFAULT_LIMIT;
- if (dcfg->resbody_access == NOT_SET) dcfg->resbody_access = 0;
- if (dcfg->of_limit == NOT_SET) dcfg->of_limit = RESPONSE_BODY_DEFAULT_LIMIT;
- if (dcfg->if_limit_action == NOT_SET) dcfg->if_limit_action = REQUEST_BODY_LIMIT_ACTION_REJECT;
- if (dcfg->of_limit_action == NOT_SET) dcfg->of_limit_action = RESPONSE_BODY_LIMIT_ACTION_REJECT;
- if (dcfg->of_mime_types == NOT_SET_P) {
- dcfg->of_mime_types = apr_table_make(dcfg->mp, 3);
- if (dcfg->of_mime_types_cleared != 1) {
- apr_table_setn(dcfg->of_mime_types, "text/plain", "1");
- apr_table_setn(dcfg->of_mime_types, "text/html", "1");
- }
- }
- if (dcfg->debuglog_fd == NOT_SET_P) dcfg->debuglog_fd = NULL;
- if (dcfg->debuglog_name == NOT_SET_P) dcfg->debuglog_name = NULL;
- if (dcfg->debuglog_level == NOT_SET) dcfg->debuglog_level = 0;
- if (dcfg->cookie_format == NOT_SET) dcfg->cookie_format = 0;
- if (dcfg->argument_separator == NOT_SET) dcfg->argument_separator = '&';
- if (dcfg->rule_inheritance == NOT_SET) dcfg->rule_inheritance = 1;
- /* audit log variables */
- if (dcfg->auditlog_flag == NOT_SET) dcfg->auditlog_flag = 0;
- if (dcfg->auditlog_type == NOT_SET) dcfg->auditlog_type = AUDITLOG_SERIAL;
- if (dcfg->auditlog_dirperms == NOT_SET) dcfg->auditlog_dirperms = CREATEMODE_DIR;
- if (dcfg->auditlog_fileperms == NOT_SET) dcfg->auditlog_fileperms = CREATEMODE;
- if (dcfg->auditlog_fd == NOT_SET_P) dcfg->auditlog_fd = NULL;
- if (dcfg->auditlog2_fd == NOT_SET_P) dcfg->auditlog2_fd = NULL;
- if (dcfg->auditlog_name == NOT_SET_P) dcfg->auditlog_name = NULL;
- if (dcfg->auditlog2_name == NOT_SET_P) dcfg->auditlog2_name = NULL;
- if (dcfg->auditlog_storage_dir == NOT_SET_P) dcfg->auditlog_storage_dir = NULL;
- if (dcfg->auditlog_parts == NOT_SET_P) dcfg->auditlog_parts = "ABCFHZ";
- if (dcfg->auditlog_relevant_regex == NOT_SET_P) dcfg->auditlog_relevant_regex = NULL;
- /* Upload */
- if (dcfg->tmp_dir == NOT_SET_P) dcfg->tmp_dir = guess_tmp_dir(dcfg->mp);
- if (dcfg->upload_dir == NOT_SET_P) dcfg->upload_dir = NULL;
- if (dcfg->upload_keep_files == NOT_SET) dcfg->upload_keep_files = KEEP_FILES_OFF;
- if (dcfg->upload_validates_files == NOT_SET) dcfg->upload_validates_files = 0;
- if (dcfg->upload_filemode == NOT_SET) dcfg->upload_filemode = 0600;
- if (dcfg->upload_file_limit == NOT_SET) dcfg->upload_file_limit = 100;
- /* Misc */
- if (dcfg->data_dir == NOT_SET_P) dcfg->data_dir = NULL;
- if (dcfg->webappid == NOT_SET_P) dcfg->webappid = "default";
- /* Content injection. */
- if (dcfg->content_injection_enabled == NOT_SET) dcfg->content_injection_enabled = 0;
- /* Stream inspection */
- if (dcfg->stream_inbody_inspection == NOT_SET) dcfg->stream_inbody_inspection = 0;
- if (dcfg->stream_outbody_inspection == NOT_SET) dcfg->stream_outbody_inspection = 0;
- /* Geo Lookup */
- if (dcfg->geo == NOT_SET_P) dcfg->geo = NULL;
- /* Gsb Lookup */
- if (dcfg->gsb == NOT_SET_P) dcfg->gsb = NULL;
- /* Unicode Map */
- if (dcfg->u_map == NOT_SET_P) dcfg->u_map = NULL;
- /* Cache */
- if (dcfg->cache_trans == NOT_SET) dcfg->cache_trans = MODSEC_CACHE_DISABLED;
- if (dcfg->cache_trans_incremental == NOT_SET) dcfg->cache_trans_incremental = 0;
- if (dcfg->cache_trans_min == (apr_size_t)NOT_SET) dcfg->cache_trans_min = 32;
- if (dcfg->cache_trans_max == (apr_size_t)NOT_SET) dcfg->cache_trans_max = 1024;
- if (dcfg->cache_trans_maxitems == (apr_size_t)NOT_SET) dcfg->cache_trans_maxitems = 512;
- if (dcfg->request_encoding == NOT_SET_P) dcfg->request_encoding = NULL;
- if (dcfg->disable_backend_compression == NOT_SET) dcfg->disable_backend_compression = 0;
- }
- /**
- *
- */
- static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
- const char *p1, const char *p2, const char *p3)
- {
- char *my_error_msg = NULL;
- msre_rule *rule = NULL;
- extern msc_engine *modsecurity;
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Rule: type=%d p1='%s' p2='%s' p3='%s'", type, p1, p2, p3);
- #endif
- /* Create a ruleset if one does not exist. */
- if ((dcfg->ruleset == NULL)||(dcfg->ruleset == NOT_SET_P)) {
- dcfg->ruleset = msre_ruleset_create(modsecurity->msre, cmd->pool);
- if (dcfg->ruleset == NULL) return FATAL_ERROR;
- }
- /* Create the rule now. */
- switch(type) {
- #if defined(WITH_LUA)
- case RULE_TYPE_LUA :
- rule = msre_rule_lua_create(dcfg->ruleset, cmd->directive->filename,
- cmd->directive->line_num, p1, p2, &my_error_msg);
- break;
- #endif
- default :
- rule = msre_rule_create(dcfg->ruleset, type, cmd->directive->filename,
- cmd->directive->line_num, p1, p2, p3, &my_error_msg);
- break;
- }
- if (rule == NULL) {
- return my_error_msg;
- }
- /* Create default actionset if one does not already exist. */
- if (dcfg->tmp_default_actionset == NULL) {
- dcfg->tmp_default_actionset = msre_actionset_create_default(modsecurity->msre);
- if (dcfg->tmp_default_actionset == NULL) return FATAL_ERROR;
- }
- /* Check some cases prior to merging so we know where it came from */
- /* Check syntax for chained rules */
- if ((rule->actionset != NULL) && (dcfg->tmp_chain_starter != NULL)) {
- /* Must NOT specify a disruptive action. */
- if (rule->actionset->intercept_action != NOT_SET) {
- return apr_psprintf(cmd->pool, "ModSecurity: Disruptive actions can only "
- "be specified by chain starter rules.");
- }
- /* Must NOT specify a skipafter action. */
- if (rule->actionset->skip_after != NOT_SET_P) {
- return apr_psprintf(cmd->pool, "ModSecurity: SkipAfter actions can only "
- "be specified by chain starter rules.");
- }
- /* Must NOT specify a phase. */
- if (rule->actionset->phase != NOT_SET) {
- return apr_psprintf(cmd->pool, "ModSecurity: Execution phases can only be "
- "specified by chain starter rules.");
- }
- /* Must NOT use metadata actions. */
- /* ENH: loop through to check for tags */
- if ((rule->actionset->id != NOT_SET_P)
- ||(rule->actionset->rev != NOT_SET_P)
- ||(rule->actionset->msg != NOT_SET_P)
- ||(rule->actionset->severity != NOT_SET)
- ||(rule->actionset->logdata != NOT_SET_P))
- {
- return apr_psprintf(cmd->pool, "ModSecurity: Metadata actions (id, rev, msg, tag, severity, logdata) "
- " can only be specified by chain starter rules.");
- }
- /* Must NOT use skip. */
- if (rule->actionset->skip_count != NOT_SET) {
- return apr_psprintf(cmd->pool, "ModSecurity: The skip action can only be used "
- " by chain starter rules. ");
- }
- }
- /* Merge actions with the parent.
- *
- * ENH Probably do not want this done fully for chained rules.
- */
- rule->actionset = msre_actionset_merge(modsecurity->msre, dcfg->tmp_default_actionset,
- rule->actionset, 1);
- /* Keep track of the parent action for "block" */
- rule->actionset->parent_intercept_action_rec = dcfg->tmp_default_actionset->intercept_action_rec;
- rule->actionset->parent_intercept_action = dcfg->tmp_default_actionset->intercept_action;
- /* Must NOT specify a disruptive action in logging phase. */
- if ((rule->actionset != NULL)
- && (rule->actionset->phase == PHASE_LOGGING)
- && (rule->actionset->intercept_action != ACTION_ALLOW)
- && (rule->actionset->intercept_action != ACTION_ALLOW_REQUEST)
- && (rule->actionset->intercept_action != ACTION_NONE)
- ) {
- return apr_psprintf(cmd->pool, "ModSecurity: Disruptive actions "
- "cannot be specified in the logging phase.");
- }
- if (dcfg->tmp_chain_starter != NULL) {
- rule->chain_starter = dcfg->tmp_chain_starter;
- rule->actionset->phase = rule->chain_starter->actionset->phase;
- }
- if (rule->actionset->is_chained != 1) {
- /* If this rule is part of the chain but does
- * not want more rules to follow in the chain
- * then cut it (the chain).
- */
- dcfg->tmp_chain_starter = NULL;
- } else {
- /* On the other hand, if this rule wants other
- * rules to follow it, then start a new chain
- * if there isn't one already.
- */
- if (dcfg->tmp_chain_starter == NULL) {
- dcfg->tmp_chain_starter = rule;
- }
- }
- /* Optimisation */
- if ((rule->op_name != NULL)&&(strcasecmp(rule->op_name, "inspectFile") == 0)) {
- dcfg->upload_validates_files = 1;
- }
- /* Create skip table if one does not already exist. */
- if (dcfg->tmp_rule_placeholders == NULL) {
- dcfg->tmp_rule_placeholders = apr_table_make(cmd->pool, 10);
- if (dcfg->tmp_rule_placeholders == NULL) return FATAL_ERROR;
- }
- /* Keep track of any rule IDs we need to skip after */
- if (rule->actionset->skip_after != NOT_SET_P) {
- char *tmp_id = apr_pstrdup(cmd->pool, rule->actionset->skip_after);
- apr_table_setn(dcfg->tmp_rule_placeholders, tmp_id, tmp_id);
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Watching for skipafter target rule id=\"%s\".", tmp_id);
- #endif
- }
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Adding rule %pp phase=%d id=\"%s\".", rule, rule->actionset->phase, (rule->actionset->id == NOT_SET_P
- ? "(none)" : rule->actionset->id));
- #endif
- /* Add rule to the recipe. */
- if (msre_ruleset_rule_add(dcfg->ruleset, rule, rule->actionset->phase) < 0) {
- return "Internal Error: Failed to add rule to the ruleset.";
- }
- /* Add an additional placeholder if this rule ID is on the list */
- if ((rule->actionset->id != NULL) && apr_table_get(dcfg->tmp_rule_placeholders, rule->actionset->id)) {
- msre_rule *phrule = apr_palloc(rule->ruleset->mp, sizeof(msre_rule));
- if (phrule == NULL) {
- return FATAL_ERROR;
- }
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Adding placeholder %pp for rule %pp id=\"%s\".", phrule, rule, rule->actionset->id);
- #endif
- /* shallow copy of original rule with placeholder marked as target */
- memcpy(phrule, rule, sizeof(msre_rule));
- phrule->placeholder = RULE_PH_SKIPAFTER;
- /* Add placeholder. */
- if (msre_ruleset_rule_add(dcfg->ruleset, phrule, phrule->actionset->phase) < 0) {
- return "Internal Error: Failed to add placeholder to the ruleset.";
- }
- /* No longer need to search for the ID */
- apr_table_unset(dcfg->tmp_rule_placeholders, rule->actionset->id);
- }
- /* Update the unparsed rule */
- rule->unparsed = msre_rule_generate_unparsed(dcfg->ruleset->mp, rule, NULL, NULL, NULL);
- return NULL;
- }
- /**
- *
- */
- static const char *add_marker(cmd_parms *cmd, directory_config *dcfg,
- const char *p1, const char *p2, const char *p3)
- {
- char *my_error_msg = NULL;
- msre_rule *rule = NULL;
- extern msc_engine *modsecurity;
- int p;
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Rule: type=%d p1='%s' p2='%s' p3='%s'", RULE_TYPE_MARKER, p1, p2, p3);
- #endif
- /* Create a ruleset if one does not exist. */
- if ((dcfg->ruleset == NULL)||(dcfg->ruleset == NOT_SET_P)) {
- dcfg->ruleset = msre_ruleset_create(modsecurity->msre, cmd->pool);
- if (dcfg->ruleset == NULL) return FATAL_ERROR;
- }
- /* Create the rule now. */
- rule = msre_rule_create(dcfg->ruleset, RULE_TYPE_MARKER, cmd->directive->filename, cmd->directive->line_num, p1, p2, p3, &my_error_msg);
- if (rule == NULL) {
- return my_error_msg;
- }
- /* This is a marker */
- rule->placeholder = RULE_PH_MARKER;
- /* Add placeholder to each phase */
- for (p = PHASE_FIRST; p <= PHASE_LAST; p++) {
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Adding marker %pp phase=%d id=\"%s\".", rule, p, (rule->actionset->id == NOT_SET_P
- ? "(none)" : rule->actionset->id));
- #endif
- if (msre_ruleset_rule_add(dcfg->ruleset, rule, p) < 0) {
- return "Internal Error: Failed to add marker to the ruleset.";
- }
- }
- /* No longer need to search for the ID */
- if (dcfg->tmp_rule_placeholders != NULL) {
- apr_table_unset(dcfg->tmp_rule_placeholders, rule->actionset->id);
- }
- return NULL;
- }
- /**
- *
- */
- static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
- const char *p1, const char *p2, int offset)
- {
- char *my_error_msg = NULL;
- msre_rule *rule = NULL;
- msre_actionset *new_actionset = NULL;
- msre_ruleset *ruleset = dcfg->ruleset;
- extern msc_engine *modsecurity;
- /* Get the ruleset if one exists */
- if ((ruleset == NULL)||(ruleset == NOT_SET_P)) {
- return NULL;
- }
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Update rule id=\"%s\" with action \"%s\".", p1, p2);
- #endif
- /* Fetch the rule */
- rule = msre_ruleset_fetch_rule(ruleset, p1, offset);
- if (rule == NULL) {
- #ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Update rule id=\"%s\" with action \"%s\" failed: Rule not found.", p1, p2);
- #endif
- return NULL;
- }
- /* Check the rule actionset */
- /* ENH: Can this happen? */
- if (rule->actionset == NULL) {
- return apr_psprintf(cmd->pool, "ModSecurity: Attempt to update action for rule \"%s\" failed: Rule does not have an actionset.", p1);
- }
- /* Create a new actionset */
- new_actionset = msre_actionset_create(modsecurity->msre, p2, &my_error_msg);
- if (new_actionset == NULL) return FATAL_ERROR;
- if (my_error_msg != NULL) return my_error_msg;
- /* Must NOT change an id */
- if ((new_actionset->id != NOT_SET_P) && (rule->actionset->id != NULL) && (strcmp(rule->actionset->id, new_actionset->id) != 0)) {
- return apr_psprintf(cmd->pool, "ModSecurity: Rule IDs cannot be updated via SecRuleUpdateActionById.");
- }
- /* Must NOT alter the phase */
- if ((new_actionset->phase != NOT_SET) && (rule->actionset->phase != new_actionset->phase)) {
- return apr_psprintf(cmd->pool, "ModSecurity: Rule phases cannot be updated via SecRuleUpdateActionById.");
- }
- #ifdef DEBUG_CONF
- {
- char *actions = msre_actionset_generate_action_string(ruleset->mp, rule->actionset);
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Update rule %pp id=\"%s\" old action: \"%s\"",
- rule,
- (rule->actionset->id == NOT_SET_P ? "(none)" : rule->actionset->id),
- actions);
- }
- #endif
- /* Merge new actions with the rule */
- /* ENH: Will this leak the old actionset? */
- rule->actionset = msre_actionset_merge(modsecurity->msre, rule->actionset,
- new_actionset, 1);
- msre_actionset_set_defaults(rule->actionset);
- /* Update the unparsed rule */
- rule->unparsed = msre_rule_generate_unparsed(ruleset->mp, rule, NULL, NULL, NULL);
- #ifdef DEBUG_CONF
- {
- char *actions = msre_actionset_generate_action_string(ruleset->mp, rule->actionset);
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Update rule %pp id=\"%s\" new action: \"%s\"",
- rule,
- (rule->actionset->id == NOT_SET_P ? "(none)" : rule->actionset->id),
- actions);
- }
- #endif
- return NULL;
- }
- /* -- Configuration directives -- */
- static const char *cmd_action(cmd_parms *cmd, void *_dcfg, const char *p1)
- {
- return add_rule(cmd, (directory_config *)_dcfg, RULE_TYPE_ACTION, SECACTION_TARGETS, SECACTION_ARGS, p1);
- }
- static const char *cmd_marker(cmd_parms *cmd, void *_dcfg, const char *p1)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- const char *action = apr_pstrcat(dcfg->mp, SECMARKER_BASE_ACTIONS, p1, NULL);
- return add_marker(cmd, (directory_config *)_dcfg, SECMARKER_TARGETS, SECMARKER_ARGS, action);
- }
- static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- if (strlen(p1) != 1) {
- return apr_psprintf(cmd->pool, "ModSecurity: Invalid argument separator: %s", p1);
- }
- dcfg->argument_separator = p1[0];
- return NULL;
- }
- static const char *cmd_audit_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
- {
- directory_config *dcfg = _dcfg;
- if (strcasecmp(p1, "On") == 0) dcfg->auditlog_flag = AUDITLOG_ON;
- else
- if (strcasecmp(p1, "Off") == 0) dcfg->auditlog_flag = AUDITLOG_OFF;
- else
- if (strcasecmp(p1, "RelevantOnly") == 0) dcfg->auditlog_flag = AUDITLOG_RELEVANT;
- else
- return (const char *)apr_psprintf(cmd->pool,
- "ModSecurity: Unrecognised parameter value for SecAuditEngine: %s", p1);
- return NULL;
- }
- static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1)
- {
- directory_config *dcfg = _dcfg;
- dcfg->auditlog_name = (char *)p1;
- if (dcfg->auditlog_name[0] == '|') {
- const char *pipe_name = dcfg->auditlog_name + 1;
- piped_log *pipe_log;
- pipe_log = ap_open_piped_log(cmd->pool, pipe_name);
- if (pipe_log == NULL) {
- return apr_psprintf(cmd->pool, "ModSecurity: Failed to open the audit log pipe: %s",
- pipe_name);
- }
- dcfg->auditlog_fd = ap_piped_log_write_fd(pipe_log);
- }
- else {
- const char *file_name = ap_server_root_relative(cmd->pool, dcfg->auditlog_name);
- apr_status_t rc;
- rc = apr_file_open(&dcfg->auditlog_fd, file_name,
- APR_WRITE | APR_APPEND | APR_CREATE | APR_BINARY,
- CREATEMODE, cmd->pool);
- if (rc != APR_SUCCESS) {
- return apr_psprintf(cmd->pool, "ModSecurity: Failed to open the audit log file: %s",
- file_name);
- }
- }
- return NULL;
- }
- static const char *cmd_audit_log2(cmd_parms *cmd, void *_dcfg, const char *p1)
- {
- directory_config *dcfg = _dcfg;
- if (dcfg->auditlog_name == NOT_SET_P) {
- return apr_psprintf(cmd->pool, "ModSecurity: Cannot configure a secondary audit log without a primary defined: %s", p1);
- }
- dcfg->auditlog2_name = (char *)p1;
- if (dcfg->auditlog2_name[0] == '|') {
- const char *pipe_name = ap_server_root_relative(cmd->pool, dcfg->auditlog2_name + 1);
- piped_log *pipe_log;
- pipe_log = ap_open_piped_log(cmd->pool, pipe_name);
- if (pipe_log == NULL) {
- return apr_psprintf(cmd->pool, "ModSecurity: Failed to open the secondary audit log pipe: %s",
- pipe_name);
- }
- dcfg->auditlog2_fd = ap_piped_log_write_fd(pipe_log);
- }
- else {
- const char *file_name = ap_server_root_relative(cmd->pool, dcfg->auditlog2_name);
- apr_status_t rc;
- rc = apr_file_open(&dcfg->auditlog2_fd, file_name,
- APR_WRITE | APR_APPEND | APR_CREATE | APR_BINARY,
- CREATEMODE, cmd->pool);
- if (rc != APR_SUCCESS) {
- return apr_psprintf(cmd->pool, "ModSecurity: Failed to open the secondary audit log file: %s",
- file_name);
- }
- }
- return NULL;
- }
- static const char *cmd_audit_log_parts(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = _dcfg;
- if (is_valid_parts_specification((char *)p1) != 1) {
- return apr_psprintf(cmd->pool, "Invalid parts specification for SecAuditLogParts: %s", p1);
- }
- dcfg->auditlog_parts = (char *)p1;
- return NULL;
- }
- static const char *cmd_audit_log_relevant_status(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = _dcfg;
- dcfg->auditlog_relevant_regex = msc_pregcomp(cmd->pool, p1, PCRE_DOTALL, NULL, NULL);
- if (dcfg->auditlog_relevant_regex == NULL) {
- return apr_psprintf(cmd->pool, "ModSecurity: Invalid regular expression: %s", p1);
- }
- return NULL;
- }
- static const char *cmd_audit_log_type(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = _dcfg;
- if (strcasecmp(p1, "Serial") == 0) dcfg->auditlog_type = AUDITLOG_SERIAL;
- else
- if (strcasecmp(p1, "Concurrent") == 0) dcfg->auditlog_type = AUDITLOG_CONCURRENT;
- else
- return (const char *)apr_psprintf(cmd->pool,
- "ModSecurity: Unrecognised parameter value for SecAuditLogType: %s", p1);
- return NULL;
- }
- static const char *cmd_audit_log_dirmode(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
- if (strcasecmp(p1, "default") == 0) {
- dcfg->auditlog_dirperms = NOT_SET;
- }
- else {
- long int mode = strtol(p1, NULL, 8); /* expects octal mode */
- if ((mode == LONG_MAX)||(mode == LONG_MIN)||(mode <= 0)||(mode > 07777)) {
- return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecAuditLogDirMode: %s", p1);
- }
- dcfg->auditlog_dirperms = mode2fileperms(mode);
- }
- return NULL;
- }
- static const char *cmd_audit_log_filemode(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
- if (strcasecmp(p1, "default") == 0) {
- dcfg->auditlog_fileperms = NOT_SET;
- }
- else {
- long int mode = strtol(p1, NULL, 8); /* expects octal mode */
- if ((mode == LONG_MAX)||(mode == LONG_MIN)||(mode <= 0)||(mode > 07777)) {
- return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecAuditLogFileMode: %s", p1);
- }
- dcfg->auditlog_fileperms = mode2fileperms(mode);
- }
- return NULL;
- }
- static const char *cmd_audit_log_storage_dir(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = _dcfg;
- dcfg->auditlog_storage_dir = ap_server_root_relative(cmd->pool, p1);
- return NULL;
- }
- static const char *cmd_cookie_format(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- if (strcmp(p1, "0") == 0) dcfg->cookie_format = COOKIES_V0;
- else
- if (strcmp(p1, "1") == 0) dcfg->cookie_format = COOKIES_V1;
- else {
- return apr_psprintf(cmd->pool, "ModSecurity: Invalid cookie format: %s", p1);
- }
- return NULL;
- }
- static const char *cmd_chroot_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
- {
- char cwd[1025] = "";
- if (cmd->server->is_virtual) {
- return "ModSecurity: SecChrootDir not allowed in VirtualHost";
- }
- chroot_dir = (char *)p1;
- if (getcwd(cwd, 1024) == NULL) {
- return "ModSecurity: Failed to get the current working directory";
- }
- if (chdir(chroot_dir) < 0) {
- return apr_psprintf(cmd->pool, "ModSecurity: Failed to chdir to %s, errno=%d (%s)",
- chroot_dir, errno, strerror(errno));
- }
- if (chdir(cwd) < 0) {
- return apr_psprintf(cmd->pool, "ModSecurity: Failed to chdir to %s, errno=%d (%s)",
- cwd, errno, strerror(errno));
- }
- return NULL;
- }
- /**
- * Adds component signature to the list of signatures kept in configuration.
- */
- static const char *cmd_component_signature(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- /* ENH Enforce "Name/VersionX.Y.Z (comment)" format. */
- *(char **)apr_array_push(dcfg->component_signatures) = (char *)p1;
- return NULL;
- }
- static const char *cmd_content_injection(cmd_parms *cmd, void *_dcfg, int flag)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
- dcfg->content_injection_enabled = flag;
- return NULL;
- }
- static const char *cmd_data_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- if (cmd->server->is_virtual) {
- return "ModSecurity: SecDataDir not allowed in VirtualHost.";
- }
- dcfg->data_dir = ap_server_root_relative(cmd->pool, p1);
- return NULL;
- }
- static const char *cmd_debug_log(cmd_parms *cmd, void *_dcfg, const char *p1)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- apr_status_t rc;
- dcfg->debuglog_name = ap_server_root_relative(cmd->pool, p1);
- rc = apr_file_open(&dcfg->debuglog_fd, dcfg->debuglog_name,
- APR_WRITE | APR_APPEND | APR_CREATE | APR_BINARY,
- CREATEMODE, cmd->pool);
- if (rc != APR_SUCCESS) {
- return apr_psprintf(cmd->pool, "ModSecurity: Failed to open debug log file: %s",
- dcfg->debuglog_name);
- }
- return NULL;
- }
- static const char *cmd_debug_log_level(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- dcfg->debuglog_level = atoi(p1);
- if ((dcfg->debuglog_level >= 0)&&(dcfg->debuglog_level <= 9)) return NULL;
- return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecDebugLogLevel: %s", p1);
- }
- static const char *cmd_default_action(cmd_parms *cmd, void *_dcfg,
- const char *p1)
- {
- directory_config *dcfg = (directory_config *)_dcfg;
- extern msc_engine *modsecurity;
- char *my_error_msg = NULL;
- dcfg->tmp_default_actionset = msre_actionset_create(modsecurity->msre, p1, &my_error_msg);
- if (dcfg->tmp_default_actionset == NULL) {
- if (my_error_msg != NULL) return my_error_msg;
- else return FATAL_ERROR;
- }
- /* Must specify a disruptive action. */
- /* ENH: Remove this requirement? */
- if (dcfg->tmp_default_actionset->intercept_action == NOT_SET) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecDefaultAction must specify a disruptive action.");
- }
- /* Must specify a phase. */
- /* ENH: Remove this requirement? */
- if (dcfg->tmp_default_actionset->phase == NOT_SET) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecDefaultAction must specify a phase.");
- }
- /* Must not use metadata actions. */
- /* ENH: loop through to check for tags */
- if ((dcfg->tmp_default_actionset->id != NOT_SET_P)
- ||(dcfg->tmp_default_actionset->rev != NOT_SET_P)
- ||(dcfg->tmp_default_actionset->msg != NOT_SET_P))
- {
- return apr_psprintf(cmd->pool, "ModSecurity: SecDefaultAction must not "
- "contain any metadata actions (id, rev, msg, tag, severity, logdata).");
- }
- /* These are just a warning for now. */
- if ((dcfg->tmp_default_actionset->severity != NOT_SET)
- ||(dcfg->tmp_default_actionset->logdata != NOT_SET_P))
- {
- ap_log_perror(APLOG_MARK,
- APLOG_STARTUP|APLOG_WARNING|APLOG_NOERRNO, 0, cmd->pool,
- "ModSecurity: WARNING Using \"severity\" or \"logdata\" in "
- "SecDefaultAction is deprecated (%s:%d).",
- cmd->directive->filename, cmd->directive->line_num);
- }
- /* Must not use chain. */
- if (dcfg->tmp_default_actionset->is_chained != NOT_SET) {
- return apr_psprintf(cmd->pool, "ModSecurity: SecDefaultAction must not "
- "contain a chain action.");
- }
- /* Must not use…
Large files files are truncated, but you can click here to view the full file