mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-10-05 14:03:12 +03:00
Update master to 2.7.3
This commit is contained in:
@@ -64,6 +64,7 @@ void *create_directory_config(apr_pool_t *mp, char *path)
|
||||
|
||||
dcfg->cookie_format = NOT_SET;
|
||||
dcfg->argument_separator = NOT_SET;
|
||||
dcfg->cookiev0_separator = NOT_SET_P;
|
||||
|
||||
dcfg->rule_inheritance = NOT_SET;
|
||||
dcfg->rule_exceptions = apr_array_make(mp, 16, sizeof(rule_exception *));
|
||||
@@ -127,6 +128,8 @@ void *create_directory_config(apr_pool_t *mp, char *path)
|
||||
dcfg->cache_trans_max = NOT_SET;
|
||||
dcfg->cache_trans_maxitems = NOT_SET;
|
||||
|
||||
/* Rule ids */
|
||||
dcfg->rule_id_htab = apr_hash_make(mp);
|
||||
dcfg->component_signatures = apr_array_make(mp, 16, sizeof(char *));
|
||||
|
||||
dcfg->request_encoding = NOT_SET_P;
|
||||
@@ -153,6 +156,9 @@ void *create_directory_config(apr_pool_t *mp, char *path)
|
||||
dcfg->crypto_hash_framesrc_pm = NOT_SET;
|
||||
|
||||
|
||||
/* xml external entity */
|
||||
dcfg->xml_external_entity = NOT_SET;
|
||||
|
||||
return dcfg;
|
||||
}
|
||||
|
||||
@@ -366,6 +372,8 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
|
||||
? parent->cookie_format : child->cookie_format);
|
||||
merged->argument_separator = (child->argument_separator == NOT_SET
|
||||
? parent->argument_separator : child->argument_separator);
|
||||
merged->cookiev0_separator = (child->cookiev0_separator == NOT_SET_P
|
||||
? parent->cookiev0_separator : child->cookiev0_separator);
|
||||
|
||||
|
||||
/* rule inheritance */
|
||||
@@ -586,6 +594,10 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
|
||||
merged->crypto_hash_framesrc_pm = (child->crypto_hash_framesrc_pm == NOT_SET
|
||||
? parent->crypto_hash_framesrc_pm : child->crypto_hash_framesrc_pm);
|
||||
|
||||
/* xml external entity */
|
||||
merged->xml_external_entity = (child->xml_external_entity == NOT_SET
|
||||
? parent->xml_external_entity : child->xml_external_entity);
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
@@ -627,6 +639,7 @@ void init_directory_config(directory_config *dcfg)
|
||||
|
||||
if (dcfg->cookie_format == NOT_SET) dcfg->cookie_format = 0;
|
||||
if (dcfg->argument_separator == NOT_SET) dcfg->argument_separator = '&';
|
||||
if (dcfg->cookiev0_separator == NOT_SET_P) dcfg->cookiev0_separator = NULL;
|
||||
|
||||
if (dcfg->rule_inheritance == NOT_SET) dcfg->rule_inheritance = 1;
|
||||
|
||||
@@ -705,6 +718,9 @@ void init_directory_config(directory_config *dcfg)
|
||||
if (dcfg->crypto_hash_iframesrc_pm == NOT_SET) dcfg->crypto_hash_iframesrc_pm = 0;
|
||||
if (dcfg->crypto_hash_framesrc_pm == NOT_SET) dcfg->crypto_hash_framesrc_pm = 0;
|
||||
|
||||
/* xml external entity */
|
||||
if (dcfg->xml_external_entity == NOT_SET) dcfg->xml_external_entity = 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -714,7 +730,9 @@ 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, *tmp_rule = NULL;
|
||||
//msre_rule *rule = NULL, *tmp_rule = NULL;
|
||||
char *rid = NULL;
|
||||
msre_rule *rule = NULL;
|
||||
extern msc_engine *modsecurity;
|
||||
int offset = 0;
|
||||
|
||||
@@ -767,9 +785,16 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
|
||||
if(type != RULE_TYPE_LUA)
|
||||
#endif
|
||||
{
|
||||
tmp_rule = msre_ruleset_fetch_rule(dcfg->ruleset, rule->actionset->id, offset);
|
||||
if(tmp_rule != NULL)
|
||||
rid = apr_hash_get(dcfg->rule_id_htab, rule->actionset->id, APR_HASH_KEY_STRING);
|
||||
if(rid != NULL) {
|
||||
return "ModSecurity: Found another rule with the same id";
|
||||
} else {
|
||||
apr_hash_set(dcfg->rule_id_htab, apr_pstrdup(dcfg->mp, rule->actionset->id), APR_HASH_KEY_STRING, apr_pstrdup(dcfg->mp, "1"));
|
||||
}
|
||||
|
||||
//tmp_rule = msre_ruleset_fetch_rule(dcfg->ruleset, rule->actionset->id, offset);
|
||||
//if(tmp_rule != NULL)
|
||||
// return "ModSecurity: Found another rule with the same id";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,6 +1109,20 @@ static const char *cmd_marker(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
return add_marker(cmd, (directory_config *)_dcfg, SECMARKER_TARGETS, SECMARKER_ARGS, action);
|
||||
}
|
||||
|
||||
static const char *cmd_cookiev0_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 cookie v0 separator: %s", p1);
|
||||
}
|
||||
|
||||
dcfg->cookiev0_separator = p1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
@@ -1919,6 +1958,10 @@ static const char *cmd_rule_update_target_by_id(cmd_parms *cmd, void *_dcfg,
|
||||
/* TODO: Validate the range here, while we can still tell the user if it's invalid */
|
||||
re->param = p1;
|
||||
|
||||
if(dcfg->ruleset == NULL) {
|
||||
return apr_psprintf(cmd->pool, "Updating target by ID with no ruleset in this context");
|
||||
}
|
||||
|
||||
return msre_ruleset_rule_update_target_matching_exception(NULL, dcfg->ruleset, re, p2, p3);
|
||||
}
|
||||
|
||||
@@ -2253,9 +2296,35 @@ static const char *cmd_sensor_id(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add SecXmlExternalEntity configuration option
|
||||
*
|
||||
* \param cmd Pointer to configuration data
|
||||
* \param _dcfg Pointer to directory configuration
|
||||
* \param p1 Pointer to configuration option
|
||||
*
|
||||
* \retval NULL On failure
|
||||
* \retval apr_psprintf On Success
|
||||
*/
|
||||
static const char *cmd_xml_external_entity(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
{
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
if (strcasecmp(p1, "on") == 0) {
|
||||
dcfg->xml_external_entity = 1;
|
||||
}
|
||||
else if (strcasecmp(p1, "off") == 0) {
|
||||
dcfg->xml_external_entity = 0;
|
||||
}
|
||||
else return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecXmlExternalEntity: %s", p1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Add SecHash configuration option
|
||||
* \brief Add SecHashEngine configuration option
|
||||
*
|
||||
* \param cmd Pointer to configuration data
|
||||
* \param _dcfg Pointer to directory configuration
|
||||
@@ -2277,7 +2346,7 @@ static const char *cmd_hash_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
|
||||
dcfg->hash_is_enabled = HASH_DISABLED;
|
||||
dcfg->hash_enforcement = HASH_DISABLED;
|
||||
}
|
||||
else return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecRuleEngine: %s", p1);
|
||||
else return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SexHashEngine: %s", p1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2767,8 +2836,21 @@ static const char *cmd_cache_transformations(cmd_parms *cmd, void *_dcfg,
|
||||
#define CMD_SCOPE_MAIN (RSRC_CONF)
|
||||
#define CMD_SCOPE_ANY (RSRC_CONF | ACCESS_CONF)
|
||||
|
||||
#if defined(HTACCESS_CONFIG)
|
||||
#define CMD_SCOPE_HTACCESS (OR_OPTIONS)
|
||||
#endif
|
||||
|
||||
const command_rec module_directives[] = {
|
||||
|
||||
#ifdef HTACCESS_CONFIG
|
||||
AP_INIT_TAKE1 (
|
||||
"SecAction",
|
||||
cmd_action,
|
||||
NULL,
|
||||
CMD_SCOPE_HTACCESS,
|
||||
"an action list"
|
||||
),
|
||||
#else
|
||||
AP_INIT_TAKE1 (
|
||||
"SecAction",
|
||||
cmd_action,
|
||||
@@ -2776,6 +2858,7 @@ const command_rec module_directives[] = {
|
||||
CMD_SCOPE_ANY,
|
||||
"an action list"
|
||||
),
|
||||
#endif
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecArgumentSeparator",
|
||||
@@ -2785,6 +2868,14 @@ const command_rec module_directives[] = {
|
||||
"character that will be used as separator when parsing application/x-www-form-urlencoded content."
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecCookiev0Separator",
|
||||
cmd_cookiev0_separator,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"character that will be used as separator when parsing cookie v0 content."
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecAuditEngine",
|
||||
cmd_audit_engine,
|
||||
@@ -3146,6 +3237,15 @@ const command_rec module_directives[] = {
|
||||
"clears the list of MIME types that will be buffered on output"
|
||||
),
|
||||
|
||||
#ifdef HTACCESS_CONFIG
|
||||
AP_INIT_TAKE23 (
|
||||
"SecRule",
|
||||
cmd_rule,
|
||||
NULL,
|
||||
CMD_SCOPE_HTACCESS,
|
||||
"rule target, operator and optional action list"
|
||||
),
|
||||
#else
|
||||
AP_INIT_TAKE23 (
|
||||
"SecRule",
|
||||
cmd_rule,
|
||||
@@ -3153,6 +3253,7 @@ const command_rec module_directives[] = {
|
||||
CMD_SCOPE_ANY,
|
||||
"rule target, operator and optional action list"
|
||||
),
|
||||
#endif
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecRuleEngine",
|
||||
@@ -3162,6 +3263,14 @@ const command_rec module_directives[] = {
|
||||
"On or Off"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecXmlExternalEntity",
|
||||
cmd_xml_external_entity,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"On or Off"
|
||||
),
|
||||
|
||||
AP_INIT_FLAG (
|
||||
"SecRuleInheritance",
|
||||
cmd_rule_inheritance,
|
||||
@@ -3178,6 +3287,31 @@ const command_rec module_directives[] = {
|
||||
"rule script and optional actionlist"
|
||||
),
|
||||
|
||||
#ifdef HTACCESS_CONFIG
|
||||
AP_INIT_ITERATE (
|
||||
"SecRuleRemoveById",
|
||||
cmd_rule_remove_by_id,
|
||||
NULL,
|
||||
CMD_SCOPE_HTACCESS,
|
||||
"rule ID for removal"
|
||||
),
|
||||
|
||||
AP_INIT_ITERATE (
|
||||
"SecRuleRemoveByTag",
|
||||
cmd_rule_remove_by_tag,
|
||||
NULL,
|
||||
CMD_SCOPE_HTACCESS,
|
||||
"rule tag for removal"
|
||||
),
|
||||
|
||||
AP_INIT_ITERATE (
|
||||
"SecRuleRemoveByMsg",
|
||||
cmd_rule_remove_by_msg,
|
||||
NULL,
|
||||
CMD_SCOPE_HTACCESS,
|
||||
"rule message for removal"
|
||||
),
|
||||
#else
|
||||
AP_INIT_ITERATE (
|
||||
"SecRuleRemoveById",
|
||||
cmd_rule_remove_by_id,
|
||||
@@ -3201,6 +3335,7 @@ const command_rec module_directives[] = {
|
||||
CMD_SCOPE_ANY,
|
||||
"rule message for removal"
|
||||
),
|
||||
#endif
|
||||
|
||||
AP_INIT_TAKE2 (
|
||||
"SecHashMethodPm",
|
||||
@@ -3218,6 +3353,39 @@ const command_rec module_directives[] = {
|
||||
"Hash method and regex"
|
||||
),
|
||||
|
||||
#ifdef HTACCESS_CONFIG
|
||||
AP_INIT_TAKE2 (
|
||||
"SecRuleUpdateActionById",
|
||||
cmd_rule_update_action_by_id,
|
||||
NULL,
|
||||
CMD_SCOPE_HTACCESS,
|
||||
"updated action list"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE23 (
|
||||
"SecRuleUpdateTargetById",
|
||||
cmd_rule_update_target_by_id,
|
||||
NULL,
|
||||
CMD_SCOPE_HTACCESS,
|
||||
"updated target list"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE23 (
|
||||
"SecRuleUpdateTargetByTag",
|
||||
cmd_rule_update_target_by_tag,
|
||||
NULL,
|
||||
CMD_SCOPE_HTACCESS,
|
||||
"rule tag pattern and updated target list"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE23 (
|
||||
"SecRuleUpdateTargetByMsg",
|
||||
cmd_rule_update_target_by_msg,
|
||||
NULL,
|
||||
CMD_SCOPE_HTACCESS,
|
||||
"rule message pattern and updated target list"
|
||||
),
|
||||
#else
|
||||
AP_INIT_TAKE2 (
|
||||
"SecRuleUpdateActionById",
|
||||
cmd_rule_update_action_by_id,
|
||||
@@ -3249,7 +3417,7 @@ const command_rec module_directives[] = {
|
||||
CMD_SCOPE_ANY,
|
||||
"rule message pattern and updated target list"
|
||||
),
|
||||
|
||||
#endif
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
"SecServerSignature",
|
||||
|
@@ -440,7 +440,11 @@ static modsec_rec *create_tx_context(request_rec *r) {
|
||||
|
||||
#if defined(WITH_LUA)
|
||||
#ifdef CACHE_LUA
|
||||
#if LUA_VERSION_NUM > 501
|
||||
msr->L = luaL_newstate();
|
||||
#else
|
||||
msr->L = lua_open();
|
||||
#endif
|
||||
luaL_openlibs(msr->L);
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -355,6 +355,8 @@ struct modsec_rec {
|
||||
|
||||
apr_size_t msc_reqbody_no_files_length;
|
||||
|
||||
char *multipart_filename;
|
||||
char *multipart_name;
|
||||
multipart_data *mpd; /* MULTIPART processor data structure */
|
||||
|
||||
xml_data *xml; /* XML processor data structure */
|
||||
@@ -468,6 +470,7 @@ struct directory_config {
|
||||
|
||||
int cookie_format;
|
||||
int argument_separator;
|
||||
const char *cookiev0_separator;
|
||||
|
||||
int rule_inheritance;
|
||||
apr_array_header_t *rule_exceptions;
|
||||
@@ -571,6 +574,9 @@ struct directory_config {
|
||||
/* Collection timeout */
|
||||
int col_timeout;
|
||||
|
||||
/* hash of ids */
|
||||
apr_hash_t *rule_id_htab;
|
||||
|
||||
/* Hash */
|
||||
apr_array_header_t *hash_method;
|
||||
const char *crypto_key;
|
||||
@@ -589,6 +595,9 @@ struct directory_config {
|
||||
int crypto_hash_location_pm;
|
||||
int crypto_hash_iframesrc_pm;
|
||||
int crypto_hash_framesrc_pm;
|
||||
|
||||
/* xml */
|
||||
int xml_external_entity;
|
||||
};
|
||||
|
||||
struct error_message_t {
|
||||
|
@@ -94,7 +94,11 @@ char *lua_compile(msc_script **script, const char *filename, apr_pool_t *pool) {
|
||||
msc_lua_dumpw_t dump;
|
||||
|
||||
/* Initialise state. */
|
||||
#if LUA_VERSION_NUM > 501
|
||||
L = luaL_newstate();
|
||||
#else
|
||||
L = lua_open();
|
||||
#endif
|
||||
luaL_openlibs(L);
|
||||
|
||||
/* Find script. */
|
||||
@@ -158,7 +162,11 @@ static apr_array_header_t *resolve_tfns(lua_State *L, int idx, modsec_rec *msr,
|
||||
if (lua_isuserdata(L, idx) || lua_isnoneornil(L, idx)) { /* No second parameter */
|
||||
return tfn_arr;
|
||||
} else if (lua_istable(L, idx)) { /* Is the second parameter an array? */
|
||||
#if LUA_VERSION_NUM > 501
|
||||
int i, n = lua_rawlen(L, idx);
|
||||
#else
|
||||
int i, n = lua_objlen(L, idx);
|
||||
#endif
|
||||
|
||||
for(i = 1; i <= n; i++) {
|
||||
lua_rawgeti(L, idx, i);
|
||||
@@ -415,7 +423,11 @@ int lua_execute(msc_script *script, char *param, modsec_rec *msr, msre_rule *rul
|
||||
lua_pop(L, rc);
|
||||
#else
|
||||
/* Create new state. */
|
||||
#if LUA_VERSION_NUM > 501
|
||||
L = luaL_newstate();
|
||||
#else
|
||||
L = lua_open();
|
||||
#endif
|
||||
luaL_openlibs(L);
|
||||
#endif
|
||||
|
||||
@@ -433,7 +445,12 @@ int lua_execute(msc_script *script, char *param, modsec_rec *msr, msre_rule *rul
|
||||
}
|
||||
|
||||
/* Register functions. */
|
||||
#if LUA_VERSION_NUM > 501
|
||||
luaL_setfuncs(L,mylib,0);
|
||||
lua_setglobal(L,"m");
|
||||
#else
|
||||
luaL_register(L, "m", mylib);
|
||||
#endif
|
||||
|
||||
rc = lua_restore(L, script);
|
||||
if (rc) {
|
||||
|
@@ -184,6 +184,8 @@ static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value)
|
||||
|
||||
validate_quotes(msr, value);
|
||||
|
||||
msr->multipart_name = apr_pstrdup(msr->mp, value);
|
||||
|
||||
if (msr->mpd->mpp->name != NULL) {
|
||||
msr_log(msr, 4, "Multipart: Warning: Duplicate Content-Disposition name: %s",
|
||||
log_escape_nq(msr->mp, value));
|
||||
@@ -201,6 +203,8 @@ static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value)
|
||||
|
||||
validate_quotes(msr, value);
|
||||
|
||||
msr->multipart_filename = apr_pstrdup(msr->mp, value);
|
||||
|
||||
if (msr->mpd->mpp->filename != NULL) {
|
||||
msr_log(msr, 4, "Multipart: Warning: Duplicate Content-Disposition filename: %s",
|
||||
log_escape_nq(msr->mp, value));
|
||||
|
@@ -35,7 +35,11 @@ int parse_cookies_v0(modsec_rec *msr, char *_cookie_header,
|
||||
cookie_header = strdup(_cookie_header);
|
||||
if (cookie_header == NULL) return -1;
|
||||
|
||||
p = apr_strtok(cookie_header, delim, &saveptr);
|
||||
if(msr->txcfg->cookiev0_separator == NULL) {
|
||||
p = apr_strtok(cookie_header, delim, &saveptr);
|
||||
} else {
|
||||
p = apr_strtok(cookie_header, msr->txcfg->cookiev0_separator, &saveptr);
|
||||
}
|
||||
|
||||
while(p != NULL) {
|
||||
attr_name = NULL;
|
||||
@@ -74,7 +78,11 @@ int parse_cookies_v0(modsec_rec *msr, char *_cookie_header,
|
||||
cookie_count++;
|
||||
}
|
||||
|
||||
p = apr_strtok(NULL, delim, &saveptr);
|
||||
if(msr->txcfg->cookiev0_separator == NULL) {
|
||||
p = apr_strtok(NULL, delim, &saveptr);
|
||||
} else {
|
||||
p = apr_strtok(NULL, msr->txcfg->cookiev0_separator, &saveptr);
|
||||
}
|
||||
}
|
||||
|
||||
free(cookie_header);
|
||||
|
@@ -21,7 +21,11 @@
|
||||
static apr_status_t msc_pcre_cleanup(msc_regex_t *regex) {
|
||||
if (regex != NULL) {
|
||||
if (regex->pe != NULL) {
|
||||
#if defined(VERSION_NGINX)
|
||||
pcre_free(regex->pe);
|
||||
#else
|
||||
free(regex->pe);
|
||||
#endif
|
||||
regex->pe = NULL;
|
||||
}
|
||||
if (regex->re != NULL) {
|
||||
@@ -71,7 +75,11 @@ void *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
|
||||
|
||||
/* Setup the pcre_extra record if pcre_study did not already do it */
|
||||
if (pe == NULL) {
|
||||
#if defined(VERSION_NGINX)
|
||||
pe = pcre_malloc(sizeof(pcre_extra));
|
||||
#else
|
||||
pe = malloc(sizeof(pcre_extra));
|
||||
#endif
|
||||
if (pe == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@
|
||||
|
||||
#define MODSEC_VERSION_MAJOR "2"
|
||||
#define MODSEC_VERSION_MINOR "7"
|
||||
#define MODSEC_VERSION_MAINT "2"
|
||||
#define MODSEC_VERSION_MAINT "3"
|
||||
#define MODSEC_VERSION_TYPE ""
|
||||
#define MODSEC_VERSION_RELEASE ""
|
||||
|
||||
@@ -53,10 +53,10 @@
|
||||
#define MODSEC_MODULE_NAME "ModSecurity for IIS (STABLE)"
|
||||
#else
|
||||
#ifdef VERSION_NGINX
|
||||
#define MODSEC_MODULE_NAME "ModSecurity for nginx (Beta)"
|
||||
#define MODSEC_MODULE_NAME "ModSecurity for nginx (RC)"
|
||||
#else
|
||||
#ifdef VERSION_STANDALONE
|
||||
#define MODSEC_MODULE_NAME "ModSecurity Standalone (Beta)"
|
||||
#define MODSEC_MODULE_NAME "ModSecurity Standalone (RC)"
|
||||
#else
|
||||
#define MODSEC_MODULE_NAME "ModSecurity for Apache"
|
||||
#endif
|
||||
|
@@ -14,17 +14,28 @@
|
||||
|
||||
#include "msc_xml.h"
|
||||
|
||||
static xmlParserInputBufferPtr
|
||||
xml_unload_external_entity(const char *URI, xmlCharEncoding enc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise XML parser.
|
||||
*/
|
||||
int xml_init(modsec_rec *msr, char **error_msg) {
|
||||
xmlParserInputBufferCreateFilenameFunc entity;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
msr->xml = apr_pcalloc(msr->mp, sizeof(xml_data));
|
||||
if (msr->xml == NULL) return -1;
|
||||
|
||||
if(msr->txcfg->xml_external_entity == 0) {
|
||||
entity = xmlParserInputBufferCreateFilenameDefault(xml_unload_external_entity);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@@ -41,9 +41,9 @@ static apr_table_t *collection_unpack(modsec_rec *msr, const unsigned char *blob
|
||||
* includes the terminating NUL and should be 1 for ""
|
||||
*/
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "BLOB[%d]: %s", blob_offset, log_escape_hex(msr->mp, blob + blob_offset, blob_size - blob_offset));
|
||||
msr_log(msr, 9, "collection_unpack: BLOB[%d]: %s", blob_offset, log_escape_hex(msr->mp, blob + blob_offset, blob_size - blob_offset));
|
||||
}
|
||||
msr_log(msr, 4, "Possibly corrupted database: var name length = 0 at blob offset %u-%u.", blob_offset, blob_offset + 1);
|
||||
msr_log(msr, 4, "collection_unpack: Possibly corrupted database: var name length = 0 at blob offset %u-%u.", blob_offset, blob_offset + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -52,9 +52,9 @@ static apr_table_t *collection_unpack(modsec_rec *msr, const unsigned char *blob
|
||||
* to 65536.
|
||||
*/
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "BLOB[%d]: %s", blob_offset, log_escape_hex(msr->mp, blob + blob_offset, blob_size - blob_offset));
|
||||
msr_log(msr, 9, "collection_unpack: BLOB[%d]: %s", blob_offset, log_escape_hex(msr->mp, blob + blob_offset, blob_size - blob_offset));
|
||||
}
|
||||
msr_log(msr, 4, "Possibly corrupted database: var name length > 65536 (0x%04x) at blob offset %u-%u.", var->name_len, blob_offset, blob_offset + 1);
|
||||
msr_log(msr, 4, "collection_unpack: Possibly corrupted database: var name length > 65536 (0x%04x) at blob offset %u-%u.", var->name_len, blob_offset, blob_offset + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ static apr_table_t *collection_unpack(modsec_rec *msr, const unsigned char *blob
|
||||
var->value_len--;
|
||||
|
||||
if (log_vars && (msr->txcfg->debuglog_level >= 9)) {
|
||||
msr_log(msr, 9, "Read variable: name \"%s\", value \"%s\".",
|
||||
msr_log(msr, 9, "collection_unpack: Read variable: name \"%s\", value \"%s\".",
|
||||
log_escape_ex(msr->mp, var->name, var->name_len),
|
||||
log_escape_ex(msr->mp, var->value, var->value_len));
|
||||
}
|
||||
@@ -102,7 +102,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
|
||||
int i;
|
||||
|
||||
if (msr->txcfg->data_dir == NULL) {
|
||||
msr_log(msr, 1, "Unable to retrieve collection (name \"%s\", key \"%s\"). Use "
|
||||
msr_log(msr, 1, "collection_retrieve_ex: Unable to retrieve collection (name \"%s\", key \"%s\"). Use "
|
||||
"SecDataDir to define data directory first.", log_escape(msr->mp, col_name),
|
||||
log_escape_ex(msr->mp, col_key, col_key_len));
|
||||
goto cleanup;
|
||||
@@ -111,7 +111,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
|
||||
dbm_filename = apr_pstrcat(msr->mp, msr->txcfg->data_dir, "/", col_name, NULL);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "collection_retrieve_ex: Retrieving collection (name \"%s\", filename \"%s\")",log_escape(msr->mp, col_name),
|
||||
msr_log(msr, 9, "collection_retrieve_ex: collection_retrieve_ex: Retrieving collection (name \"%s\", filename \"%s\")",log_escape(msr->mp, col_name),
|
||||
log_escape(msr->mp, dbm_filename));
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
|
||||
value = (apr_sdbm_datum_t *)apr_pcalloc(msr->mp, sizeof(apr_sdbm_datum_t));
|
||||
rc = apr_sdbm_fetch(dbm, value, key);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Failed to read from DBM file \"%s\": %s", log_escape(msr->mp,
|
||||
msr_log(msr, 1, "collection_retrieve_ex: Failed to read from DBM file \"%s\": %s", log_escape(msr->mp,
|
||||
dbm_filename), get_apr_error(msr->mp, rc));
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -177,15 +177,15 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
|
||||
}
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Removing key \"%s\" from collection.", key_to_expire + 9);
|
||||
msr_log(msr, 9, "Removing key \"%s\" from collection.", key_to_expire);
|
||||
msr_log(msr, 9, "collection_retrieve_ex: Removing key \"%s\" from collection.", key_to_expire + 9);
|
||||
msr_log(msr, 9, "collection_retrieve_ex: Removing key \"%s\" from collection.", key_to_expire);
|
||||
}
|
||||
|
||||
apr_table_unset(col, key_to_expire + 9);
|
||||
apr_table_unset(col, key_to_expire);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Removed expired variable \"%s\".", key_to_expire + 9);
|
||||
msr_log(msr, 4, "collection_retrieve_ex: Removed expired variable \"%s\".", key_to_expire + 9);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -205,7 +205,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
|
||||
rc = apr_sdbm_open(&dbm, dbm_filename, APR_CREATE | APR_WRITE | APR_SHARELOCK,
|
||||
CREATEMODE, msr->mp);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Failed to access DBM file \"%s\": %s",
|
||||
msr_log(msr, 1, "collection_retrieve_ex: Failed to access DBM file \"%s\": %s",
|
||||
log_escape(msr->mp, dbm_filename), get_apr_error(msr->mp, rc));
|
||||
dbm = NULL;
|
||||
goto cleanup;
|
||||
@@ -217,7 +217,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
|
||||
|
||||
rc = apr_sdbm_delete(dbm, key);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Failed deleting collection (name \"%s\", "
|
||||
msr_log(msr, 1, "collection_retrieve_ex: Failed deleting collection (name \"%s\", "
|
||||
"key \"%s\"): %s", log_escape(msr->mp, col_name),
|
||||
log_escape_ex(msr->mp, col_key, col_key_len), get_apr_error(msr->mp, rc));
|
||||
goto cleanup;
|
||||
@@ -230,11 +230,11 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
|
||||
}
|
||||
|
||||
if (expired && (msr->txcfg->debuglog_level >= 9)) {
|
||||
msr_log(msr, 9, "Collection expired (name \"%s\", key \"%s\").", col_name,
|
||||
msr_log(msr, 9, "collection_retrieve_ex: Collection expired (name \"%s\", key \"%s\").", col_name,
|
||||
log_escape_ex(msr->mp, col_key, col_key_len));
|
||||
}
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Deleted collection (name \"%s\", key \"%s\").",
|
||||
msr_log(msr, 4, "collection_retrieve_ex: Deleted collection (name \"%s\", key \"%s\").",
|
||||
log_escape(msr->mp, col_name), log_escape_ex(msr->mp, col_key, col_key_len));
|
||||
}
|
||||
goto cleanup;
|
||||
@@ -278,13 +278,13 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
|
||||
}
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Retrieved collection (name \"%s\", key \"%s\").",
|
||||
msr_log(msr, 4, "collection_retrieve_ex: Retrieved collection (name \"%s\", key \"%s\").",
|
||||
log_escape(msr->mp, col_name), log_escape_ex(msr->mp, col_key, col_key_len));
|
||||
}
|
||||
|
||||
if ((existing_dbm == NULL) && dbm) {
|
||||
/* Should not ever get here */
|
||||
msr_log(msr, 1, "Internal Error: Collection remained open (name \"%s\", key \"%s\").",
|
||||
msr_log(msr, 1, "collection_retrieve_ex: Internal Error: Collection remained open (name \"%s\", key \"%s\").",
|
||||
log_escape(msr->mp, col_name), log_escape_ex(msr->mp, col_key, col_key_len));
|
||||
|
||||
apr_sdbm_close(dbm);
|
||||
@@ -346,7 +346,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
}
|
||||
|
||||
if (msr->txcfg->data_dir == NULL) {
|
||||
msr_log(msr, 1, "Unable to store collection (name \"%s\", key \"%s\"). Use "
|
||||
msr_log(msr, 1, "collection_store: Unable to store collection (name \"%s\", key \"%s\"). Use "
|
||||
"SecDataDir to define data directory first.", log_escape_ex(msr->mp, var_name->value, var_name->value_len),
|
||||
log_escape_ex(msr->mp, var_key->value, var_key->value_len));
|
||||
goto error;
|
||||
@@ -416,7 +416,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
rc = apr_sdbm_open(&dbm, dbm_filename, APR_CREATE | APR_WRITE | APR_SHARELOCK,
|
||||
CREATEMODE, msr->mp);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Failed to access DBM file \"%s\": %s", log_escape(msr->mp, dbm_filename),
|
||||
msr_log(msr, 1, "collection_store: Failed to access DBM file \"%s\": %s", log_escape(msr->mp, dbm_filename),
|
||||
get_apr_error(msr->mp, rc));
|
||||
dbm = NULL;
|
||||
goto error;
|
||||
@@ -425,7 +425,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
/* Need to lock to pull in the stored data again and apply deltas. */
|
||||
rc = apr_sdbm_lock(dbm, APR_FLOCK_EXCLUSIVE);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Failed to exclusivly lock DBM file \"%s\": %s", log_escape(msr->mp, dbm_filename),
|
||||
msr_log(msr, 1, "collection_store: Failed to exclusivly lock DBM file \"%s\": %s", log_escape(msr->mp, dbm_filename),
|
||||
get_apr_error(msr->mp, rc));
|
||||
goto error;
|
||||
}
|
||||
@@ -435,7 +435,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
orig_col = (const apr_table_t *)apr_table_get(msr->collections_original, var_name->value);
|
||||
if (orig_col != NULL) {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Re-retrieving collection prior to store: %s",
|
||||
msr_log(msr, 9, "collection_store: Re-retrieving collection prior to store: %s",
|
||||
apr_psprintf(msr->mp, "%.*s", var_name->value_len, var_name->value));
|
||||
}
|
||||
|
||||
@@ -469,7 +469,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
var->value_len = strlen(var->value);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Delta applied for %s.%s %d->%d (%d): %d + (%d) = %d [%s,%d]",
|
||||
msr_log(msr, 9, "collection_store: Delta applied for %s.%s %d->%d (%d): %d + (%d) = %d [%s,%d]",
|
||||
log_escape_ex(msr->mp, var_name->value, var_name->value_len),
|
||||
log_escape_ex(msr->mp, var->name, var->name_len),
|
||||
origval, ourval, delta, storedval, delta, newval, var->value, var->value_len);
|
||||
@@ -523,7 +523,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
blob_offset += 2 + len;
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Wrote variable: name \"%s\", value \"%s\".",
|
||||
msr_log(msr, 9, "collection_store: Wrote variable: name \"%s\", value \"%s\".",
|
||||
log_escape_ex(msr->mp, var->name, var->name_len),
|
||||
log_escape_ex(msr->mp, var->value, var->value_len));
|
||||
}
|
||||
@@ -541,7 +541,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
|
||||
rc = apr_sdbm_store(dbm, key, value, APR_SDBM_REPLACE);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Failed to write to DBM file \"%s\": %s", dbm_filename,
|
||||
msr_log(msr, 1, "collection_store: Failed to write to DBM file \"%s\": %s", dbm_filename,
|
||||
get_apr_error(msr->mp, rc));
|
||||
goto error;
|
||||
}
|
||||
@@ -549,7 +549,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
|
||||
apr_sdbm_close(dbm);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Persisted collection (name \"%s\", key \"%s\").",
|
||||
msr_log(msr, 4, "collection_store: Persisted collection (name \"%s\", key \"%s\").",
|
||||
log_escape_ex(msr->mp, var_name->value, var_name->value_len),
|
||||
log_escape_ex(msr->mp, var_key->value, var_key->value_len));
|
||||
}
|
||||
@@ -599,7 +599,7 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
|
||||
rc = apr_sdbm_open(&dbm, dbm_filename, APR_CREATE | APR_WRITE | APR_SHARELOCK,
|
||||
CREATEMODE, msr->mp);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Failed to access DBM file \"%s\": %s", log_escape(msr->mp, dbm_filename),
|
||||
msr_log(msr, 1, "collections_remove_stale: Failed to access DBM file \"%s\": %s", log_escape(msr->mp, dbm_filename),
|
||||
get_apr_error(msr->mp, rc));
|
||||
dbm = NULL;
|
||||
goto error;
|
||||
@@ -609,7 +609,7 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
|
||||
keys_arr = apr_array_make(msr->mp, 256, sizeof(char *));
|
||||
rc = apr_sdbm_lock(dbm, APR_FLOCK_SHARED);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Failed to lock DBM file \"%s\": %s", log_escape(msr->mp, dbm_filename),
|
||||
msr_log(msr, 1, "collections_remove_stale: Failed to lock DBM file \"%s\": %s", log_escape(msr->mp, dbm_filename),
|
||||
get_apr_error(msr->mp, rc));
|
||||
goto error;
|
||||
}
|
||||
@@ -626,7 +626,7 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
|
||||
apr_sdbm_unlock(dbm);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Found %d record(s) in file \"%s\".", keys_arr->nelts,
|
||||
msr_log(msr, 9, "collections_remove_stale: Found %d record(s) in file \"%s\".", keys_arr->nelts,
|
||||
log_escape(msr->mp, dbm_filename));
|
||||
}
|
||||
|
||||
@@ -638,7 +638,7 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
|
||||
|
||||
rc = apr_sdbm_fetch(dbm, &value, key);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Failed reading DBM file \"%s\": %s",
|
||||
msr_log(msr, 1, "collections_remove_stale: Failed reading DBM file \"%s\": %s",
|
||||
log_escape(msr->mp, dbm_filename), get_apr_error(msr->mp, rc));
|
||||
goto error;
|
||||
}
|
||||
@@ -654,14 +654,14 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
|
||||
|
||||
var = (msc_string *)apr_table_get(col, "__expire_KEY");
|
||||
if (var == NULL) {
|
||||
msr_log(msr, 1, "Collection cleanup discovered entry with no "
|
||||
msr_log(msr, 1, "collections_remove_stale: Collection cleanup discovered entry with no "
|
||||
"__expire_KEY (name \"%s\", key \"%s\").",
|
||||
log_escape(msr->mp, col_name), log_escape_ex(msr->mp, key.dptr, key.dsize - 1));
|
||||
} else {
|
||||
unsigned int expiry_time = atoi(var->value);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "Record (name \"%s\", key \"%s\") set to expire in %" APR_TIME_T_FMT " seconds.",
|
||||
msr_log(msr, 9, "collections_remove_stale: Record (name \"%s\", key \"%s\") set to expire in %" APR_TIME_T_FMT " seconds.",
|
||||
log_escape(msr->mp, col_name), log_escape_ex(msr->mp, key.dptr, key.dsize - 1),
|
||||
expiry_time - now);
|
||||
}
|
||||
@@ -669,14 +669,14 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
|
||||
if (expiry_time <= now) {
|
||||
rc = apr_sdbm_delete(dbm, key);
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Failed deleting collection (name \"%s\", "
|
||||
msr_log(msr, 1, "collections_remove_stale: Failed deleting collection (name \"%s\", "
|
||||
"key \"%s\"): %s", log_escape(msr->mp, col_name),
|
||||
log_escape_ex(msr->mp, key.dptr, key.dsize - 1), get_apr_error(msr->mp, rc));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 4) {
|
||||
msr_log(msr, 4, "Removed stale collection (name \"%s\", "
|
||||
msr_log(msr, 4, "collections_remove_stale: Removed stale collection (name \"%s\", "
|
||||
"key \"%s\").", log_escape(msr->mp, col_name),
|
||||
log_escape_ex(msr->mp, key.dptr, key.dsize - 1));
|
||||
}
|
||||
|
@@ -161,7 +161,7 @@ char *msre_ruleset_rule_update_target_matching_exception(modsec_rec *msr, msre_r
|
||||
char *err;
|
||||
|
||||
if(ruleset == NULL)
|
||||
return apr_psprintf(ruleset->mp, "No ruleset present");
|
||||
return NULL;
|
||||
|
||||
if(p2 == NULL) {
|
||||
return apr_psprintf(ruleset->mp, "Trying to update without a target");
|
||||
@@ -353,7 +353,7 @@ char *update_rule_target_ex(modsec_rec *msr, msre_ruleset *ruleset, msre_rule *r
|
||||
}
|
||||
#if !defined(MSC_TEST)
|
||||
else {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, " ModSecurity: Error parseing rule targets to replace variable");
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, " ModSecurity: Error parsing rule targets to replace variable");
|
||||
}
|
||||
#endif
|
||||
goto end;
|
||||
|
@@ -1289,6 +1289,22 @@ static int var_modsec_build_generate(modsec_rec *msr, msre_var *var, msre_rule *
|
||||
return var_simple_generate(var, vartab, mptmp, modsec_build(mptmp));
|
||||
}
|
||||
|
||||
/* MULTIPART_FILENAME */
|
||||
|
||||
static int var_multipart_filename_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
return var_simple_generate(var, vartab, mptmp, msr->multipart_filename);
|
||||
}
|
||||
|
||||
/* MULTIPART_NAME */
|
||||
|
||||
static int var_multipart_name_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
return var_simple_generate(var, vartab, mptmp, msr->multipart_name);
|
||||
}
|
||||
|
||||
/* MULTIPART_BOUNDARY_QUOTED */
|
||||
|
||||
static int var_multipart_boundary_quoted_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
@@ -2813,6 +2829,28 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
/* MULTIPART_FILENAME */
|
||||
msre_engine_variable_register(engine,
|
||||
"MULTIPART_FILENAME",
|
||||
VAR_SIMPLE,
|
||||
0, 0,
|
||||
NULL,
|
||||
var_multipart_filename_generate,
|
||||
VAR_CACHE,
|
||||
PHASE_REQUEST_BODY
|
||||
);
|
||||
|
||||
/* MULTIPART_NAME */
|
||||
msre_engine_variable_register(engine,
|
||||
"MULTIPART_NAME",
|
||||
VAR_SIMPLE,
|
||||
0, 0,
|
||||
NULL,
|
||||
var_multipart_name_generate,
|
||||
VAR_CACHE,
|
||||
PHASE_REQUEST_BODY
|
||||
);
|
||||
|
||||
/* MULTIPART_BOUNDARY_QUOTED */
|
||||
msre_engine_variable_register(engine,
|
||||
"MULTIPART_BOUNDARY_QUOTED",
|
||||
|
Reference in New Issue
Block a user