mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-13 21:36:00 +03:00
Fixing code based on review comments...
Cleaned up what vars are cacheable. Added parens around "*foo++" where it clarified the operation to be "*(foo++)". Added " at VARNAME" to operator matches where needed. Escaped var->name in the var generation (user-supplied data). Marked a bunch of TODOs as ENHs instead. Transformed some C++ style comments to C style. Removed the %0-9 macros code which was commented out. Optimized some ctl action code so that multiple ifs are else ifs. Implemented some error messages marked as ENH. Make commented out acmp debugging a configure-time option. Cleanup GEO debug log messages. Added relative filename support for geo dbs. Added help text to Sec* directives.
This commit is contained in:
parent
99c41afc3d
commit
9fb03d277d
3
CHANGES
3
CHANGES
@ -225,8 +225,7 @@ Changes since 2.5.0-dev2:
|
||||
|
||||
* Fixed decoding full-width unicode in t:urlDecodeUni.
|
||||
|
||||
* Lessen some overhead of debugging messages and calculations
|
||||
TODO: more to come
|
||||
* Lessen some overhead of debugging messages and calculations.
|
||||
|
||||
* Removed strnlen() calls for non-GNU platforms.
|
||||
|
||||
|
@ -178,11 +178,11 @@ static void acmp_strtoucs(ACMP *parser, const char *str, acmp_utf8_char_t *ucs_c
|
||||
|
||||
if (parser->is_utf8 == 0) {
|
||||
for (i = 0; i < len; i++) {
|
||||
*ucs_chars++ = *c++;
|
||||
*(ucs_chars++) = *(c++);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < len; i++) {
|
||||
*ucs_chars++ = utf8_decodechar(c);
|
||||
*(ucs_chars++) = utf8_decodechar(c);
|
||||
c += utf8_seq_len(c);
|
||||
}
|
||||
}
|
||||
@ -275,7 +275,6 @@ static inline acmp_node_t *acmp_btree_find(acmp_node_t *node, acmp_utf8_char_t l
|
||||
*
|
||||
*/
|
||||
static inline acmp_node_t *acmp_goto(acmp_node_t *node, acmp_utf8_char_t letter) {
|
||||
//return acmp_child_for_code(node, letter);
|
||||
return acmp_btree_find(node, letter);
|
||||
}
|
||||
|
||||
@ -313,14 +312,18 @@ static void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[],
|
||||
node->left = apr_pcalloc(pool, sizeof(acmp_btree_node_t));
|
||||
node->left->node = nodes[left];
|
||||
node->left->letter = nodes[left]->letter;
|
||||
/* printf("%c ->left %c \n", node->node->letter, node->left->node->letter); */
|
||||
#ifdef DEBUG_ACMP
|
||||
fprintf(stderr, "%lc ->left %lc\n", (wint_t)node->node->letter, (wint_t)node->left->node->letter);
|
||||
#endif
|
||||
}
|
||||
if ((rb - pos) > 1) {
|
||||
right = pos + (rb - pos) / 2;
|
||||
node->right = apr_pcalloc(pool, sizeof(acmp_btree_node_t));
|
||||
node->right->node = nodes[right];
|
||||
node->right->letter = nodes[right]->letter;
|
||||
/* printf("%c ->right %c \n", node->node->letter, node->right->node->letter); */
|
||||
#ifdef DEBUG_ACMP
|
||||
fprintf(stderr, "%lc ->right %lc\n", (wint_t)node->node->letter, (wint_t)node->right->node->letter);
|
||||
#endif
|
||||
}
|
||||
if (node->right != NULL) {
|
||||
acmp_add_btree_leaves(node->right, nodes, right, pos, rb, pool);
|
||||
@ -382,7 +385,9 @@ static apr_status_t acmp_connect_fail_branches(ACMP *parser) {
|
||||
for (child = parser->root_node->child; child != NULL; child = child->sibling) {
|
||||
child->fail = parser->root_node;
|
||||
*(acmp_node_t **)apr_array_push(arr) = child;
|
||||
/* printf("fail direction: *%s* => *%s*\n", child->text, child->fail->text); */
|
||||
#ifdef DEBUG_ACMP
|
||||
fprintf(stderr, "fail direction: *%s* => *%s*\n", child->text, child->fail->text);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
@ -393,7 +398,9 @@ static apr_status_t acmp_connect_fail_branches(ACMP *parser) {
|
||||
goto_node = acmp_child_for_code(node->parent->fail, node->letter);
|
||||
node->fail = (goto_node != NULL) ? goto_node : parser->root_node;
|
||||
}
|
||||
/* printf("fail direction: *%s* => *%s*\n", node->text, node->fail->text); */
|
||||
#ifdef DEBUG_ACMP
|
||||
fprintf(stderr, "fail direction: *%s* => *%s*\n", node->text, node->fail->text);
|
||||
#endif
|
||||
child = node->child;
|
||||
while (child != NULL) {
|
||||
*(acmp_node_t **)apr_array_push(arr2) = child;
|
||||
|
@ -584,12 +584,14 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
|
||||
}
|
||||
|
||||
/* 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) "
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: Metadata actions (id, rev, msg, tag, severity, logdata) "
|
||||
" can only be specified by chain starter rules.");
|
||||
}
|
||||
|
||||
@ -676,6 +678,9 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
|
||||
/* 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,
|
||||
@ -699,7 +704,7 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
*/
|
||||
static const char *add_marker(cmd_parms *cmd, directory_config *dcfg, const char *p1,
|
||||
const char *p2, const char *p3)
|
||||
@ -934,7 +939,7 @@ static const char *cmd_chroot_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
static const char *cmd_component_signature(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
/* TODO Enforce "Name/VersionX.Y.Z (comment)" format. */
|
||||
/* ENH Enforce "Name/VersionX.Y.Z (comment)" format. */
|
||||
*(char **)apr_array_push(dcfg->component_signatures) = (char *)p1;
|
||||
|
||||
return NULL;
|
||||
@ -1008,13 +1013,15 @@ static const char *cmd_default_action(cmd_parms *cmd, void *_dcfg, const char *p
|
||||
}
|
||||
|
||||
/* 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)
|
||||
||(dcfg->tmp_default_actionset->severity != NOT_SET)
|
||||
||(dcfg->tmp_default_actionset->logdata != NOT_SET_P))
|
||||
{
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: SecDefaultAction must not "
|
||||
"contain any metadata actions (id, rev, msg).");
|
||||
"contain any metadata actions (id, rev, msg, tag, severity, logdata).");
|
||||
}
|
||||
|
||||
/* Must not use chain. */
|
||||
@ -1146,8 +1153,7 @@ static const char *cmd_request_encoding(cmd_parms *cmd, void *_dcfg, const char
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
// TODO Validate encoding
|
||||
// return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecRequestBodyAccess: %s", p1);
|
||||
/* ENH Validate encoding */
|
||||
|
||||
dcfg->request_encoding = p1;
|
||||
|
||||
@ -1202,7 +1208,7 @@ static const char *cmd_response_body_mime_type(cmd_parms *cmd, void *_dcfg, cons
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
char *p1 = apr_pstrdup(cmd->pool, _p1);
|
||||
|
||||
// TODO check whether the parameter is a valid MIME type of "null"
|
||||
/* TODO check whether the parameter is a valid MIME type of "???" */
|
||||
|
||||
if ((dcfg->of_mime_types == NULL)||(dcfg->of_mime_types == NOT_SET_P)) {
|
||||
dcfg->of_mime_types = apr_table_make(cmd->pool, 10);
|
||||
@ -1381,7 +1387,7 @@ static const char *cmd_upload_keep_files(cmd_parms *cmd, void *_dcfg, const char
|
||||
static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
|
||||
// TODO enforce format (letters, digits, ., _, -)
|
||||
/* ENH enforce format (letters, digits, ., _, -) */
|
||||
dcfg->webappid = p1;
|
||||
|
||||
return NULL;
|
||||
@ -1466,11 +1472,12 @@ static const char *cmd_pdf_protect_method(cmd_parms *cmd, void *_dcfg,
|
||||
static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1)
|
||||
{
|
||||
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
|
||||
char *error_msg;
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
if (dcfg == NULL) return NULL;
|
||||
|
||||
if (geo_init(dcfg, p1, &error_msg) <= 0) {
|
||||
if (geo_init(dcfg, filename, &error_msg) <= 0) {
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
@ -1569,7 +1576,7 @@ const command_rec module_directives[] = {
|
||||
cmd_action,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"an action list"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1593,7 +1600,7 @@ const command_rec module_directives[] = {
|
||||
cmd_audit_log,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"The filename of the primary audit log file"
|
||||
"filename of the primary audit log file"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1601,7 +1608,7 @@ const command_rec module_directives[] = {
|
||||
cmd_audit_log2,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"The filename of the secondary audit log file"
|
||||
"filename of the secondary audit log file"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1681,7 +1688,7 @@ const command_rec module_directives[] = {
|
||||
cmd_data_dir,
|
||||
NULL,
|
||||
CMD_SCOPE_MAIN,
|
||||
"" // TODO
|
||||
"path to the persistent data storage area" // TODO
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1706,7 +1713,7 @@ const command_rec module_directives[] = {
|
||||
cmd_default_action,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"default action list"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1834,7 +1841,7 @@ const command_rec module_directives[] = {
|
||||
cmd_response_body_limit,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"byte limit for response body"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1842,7 +1849,7 @@ const command_rec module_directives[] = {
|
||||
cmd_response_body_limit_action,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"what happens when the response body limit is reached"
|
||||
),
|
||||
|
||||
AP_INIT_ITERATE (
|
||||
@ -1866,7 +1873,7 @@ const command_rec module_directives[] = {
|
||||
cmd_rule,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"rule target, operator and optional action list"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1890,7 +1897,7 @@ const command_rec module_directives[] = {
|
||||
cmd_rule_script,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"rule script and optional actionlist"
|
||||
),
|
||||
|
||||
AP_INIT_ITERATE (
|
||||
@ -1898,7 +1905,7 @@ const command_rec module_directives[] = {
|
||||
cmd_rule_remove_by_id,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"rule ID for removal"
|
||||
),
|
||||
|
||||
AP_INIT_ITERATE (
|
||||
@ -1906,7 +1913,7 @@ const command_rec module_directives[] = {
|
||||
cmd_rule_remove_by_msg,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"rule message for removal"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1914,7 +1921,7 @@ const command_rec module_directives[] = {
|
||||
cmd_server_signature,
|
||||
NULL,
|
||||
CMD_SCOPE_MAIN,
|
||||
"The new signature of the server"
|
||||
"the new signature of the server"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1922,7 +1929,7 @@ const command_rec module_directives[] = {
|
||||
cmd_tmp_dir,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"path to the temporary storage area"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1930,7 +1937,7 @@ const command_rec module_directives[] = {
|
||||
cmd_upload_dir,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"path to the file upload area"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1938,7 +1945,7 @@ const command_rec module_directives[] = {
|
||||
cmd_upload_keep_files,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"On or Off"
|
||||
),
|
||||
|
||||
AP_INIT_TAKE1 (
|
||||
@ -1946,7 +1953,7 @@ const command_rec module_directives[] = {
|
||||
cmd_web_app_id,
|
||||
NULL,
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
"id"
|
||||
),
|
||||
|
||||
{ NULL }
|
||||
|
@ -150,6 +150,21 @@ AC_ARG_ENABLE(debug-cache,
|
||||
debug_cache=
|
||||
])
|
||||
|
||||
# DEBUG_ACMP
|
||||
AC_ARG_ENABLE(debug-acmp,
|
||||
AS_HELP_STRING([--enable-debug-acmp],
|
||||
[Enable debugging acmp code.]),
|
||||
[
|
||||
if test "$enableval" != "no"; then
|
||||
debug_acmp="-DDEBUG_ACMP"
|
||||
else
|
||||
debug_acmp=
|
||||
fi
|
||||
],
|
||||
[
|
||||
debug_acmp=
|
||||
])
|
||||
|
||||
# PERFORMANCE_MEASUREMENT
|
||||
AC_ARG_ENABLE(performance-measurement,
|
||||
AS_HELP_STRING([--enable-performance-measurement],
|
||||
@ -183,7 +198,7 @@ AC_ARG_ENABLE(modsec-api,
|
||||
### Build *EXTRA_CFLAGS vars
|
||||
|
||||
EXTRA_CFLAGS="-O2 -g -Wall -Werror"
|
||||
MODSEC_EXTRA_CFLAGS="$debug_conf $debug_cache $perf_meas $modsec_api"
|
||||
MODSEC_EXTRA_CFLAGS="$debug_conf $debug_cache $debug_acmp $perf_meas $modsec_api"
|
||||
|
||||
APXS_EXTRA_CFLAGS=""
|
||||
for f in $EXTRA_CFLAGS; do
|
||||
|
@ -419,9 +419,6 @@ static apr_status_t module_cleanup(void *data) {
|
||||
* Pre-configuration initialisation hook.
|
||||
*/
|
||||
static int hook_pre_config(apr_pool_t *mp, apr_pool_t *mp_log, apr_pool_t *mp_temp) {
|
||||
/* Add the MODSEC_a.b define */
|
||||
*(char **)apr_array_push(ap_server_config_defines) = apr_psprintf(mp, "MODSEC_%s.%s", MODSEC_VERSION_MAJOR, MODSEC_VERSION_MINOR);
|
||||
|
||||
/* Initialise ModSecurity engine */
|
||||
modsecurity = modsecurity_create(mp, MODSEC_ONLINE);
|
||||
if (modsecurity == NULL) {
|
||||
@ -697,8 +694,9 @@ static int hook_request_late(request_rec *r) {
|
||||
/* Update the request headers. They might have changed after
|
||||
* the body was read (trailers).
|
||||
*/
|
||||
// TODO We still need to keep a copy of the original headers
|
||||
// to log in the audit log.
|
||||
/* NOTE We still need to keep a copy of the original headers
|
||||
* to log in the audit log.
|
||||
*/
|
||||
msr->request_headers = apr_table_copy(msr->mp, r->headers_in);
|
||||
|
||||
/* Process phase REQUEST_BODY */
|
||||
@ -1070,6 +1068,9 @@ static void register_hooks(apr_pool_t *mp) {
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Add the MODSEC_a.b define */
|
||||
*(char **)apr_array_push(ap_server_config_defines) = apr_psprintf(mp, "MODSEC_%s.%s", MODSEC_VERSION_MAJOR, MODSEC_VERSION_MINOR);
|
||||
|
||||
#if (!defined(NO_MODSEC_API))
|
||||
/* Export optional functions. */
|
||||
APR_REGISTER_OPTIONAL_FN(modsec_register_tfn);
|
||||
|
@ -355,10 +355,8 @@ int geo_lookup(modsec_rec *msr, geo_rec *georec, const char *target, char **erro
|
||||
*error_msg = apr_psprintf(msr->mp, "No geo data for \"%s\".", target);
|
||||
return 0;
|
||||
}
|
||||
msr_log(msr, 9, "GEO: rec=\"%s\"", log_escape_raw(msr->mp, buf, sizeof(buf)));
|
||||
|
||||
/* Country */
|
||||
msr_log(msr, 9, "GEO: country=\"%.*s\"", (1*4), log_escape_raw(msr->mp, (unsigned char *)&rec_val, 1));
|
||||
georec->country_code = geo_country_code[country];
|
||||
georec->country_code3 = geo_country_code3[country];
|
||||
georec->country_name = geo_country_name[country];
|
||||
|
@ -47,7 +47,7 @@ static int sec_auditlog_write(modsec_rec *msr, const char *data, unsigned int le
|
||||
* out-of-disk-space events and to prevent further attempts
|
||||
* to write to the same file in this request.
|
||||
*
|
||||
* Note that, as we opened the file throught the pool mechanism of
|
||||
* Note that, as we opened the file through the pool mechanism of
|
||||
* the APR, we do not need to close the file here. It will be closed
|
||||
* automatically at the end of the request.
|
||||
*/
|
||||
@ -411,7 +411,7 @@ void sec_audit_logger(modsec_rec *msr) {
|
||||
* writing to but it's not us that's causing the problem
|
||||
* and there isn't anything we can do about that.
|
||||
*
|
||||
* TODO Actually there is something we can do! We will make
|
||||
* ENH Actually there is something we can do! We will make
|
||||
* SecAuditStorageDir mandatory, ask the user to explicitly
|
||||
* define the storage location *and* refuse to work if the
|
||||
* index and the storage location are in the same folder.
|
||||
@ -874,7 +874,7 @@ void sec_audit_logger(modsec_rec *msr) {
|
||||
}
|
||||
|
||||
/* AUDITLOG_PART_UPLOADS */
|
||||
// TODO: Implement
|
||||
/* ENH: Implement */
|
||||
|
||||
|
||||
/* AUDITLOG_PART_MATCHEDRULES */
|
||||
|
@ -153,7 +153,7 @@ static apr_array_header_t *resolve_tfns(lua_State *L, int idx, modsec_rec *msr,
|
||||
*(msre_tfn_metadata **)apr_array_push(tfn_arr) = tfn;
|
||||
}
|
||||
} else {
|
||||
// TODO Error
|
||||
msr_log(msr, 1, "SecRuleScript: Transformation parameter must be a transformation name or array of transformation names.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -360,7 +360,7 @@ int lua_execute(msc_script *script, char *param, modsec_rec *msr, msre_rule *rul
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get the response from the script.
|
||||
/* Get the response from the script. */
|
||||
*error_msg = (char *)lua_tostring(L, -1);
|
||||
if (*error_msg != NULL) {
|
||||
*error_msg = apr_pstrdup(msr->mp, *error_msg);
|
||||
|
@ -124,7 +124,7 @@ static int multipart_parse_content_disposition(modsec_rec *msr, char *c_d_value)
|
||||
break;
|
||||
}
|
||||
|
||||
*t++ = *p++;
|
||||
*(t++) = *(p++);
|
||||
}
|
||||
if (*p == '\0') return -10;
|
||||
|
||||
@ -283,7 +283,7 @@ static int multipart_process_part_header(modsec_rec *msr, char **error_msg) {
|
||||
log_escape(msr->mp, data));
|
||||
}
|
||||
|
||||
if (strlen(new_value) > 4096) {
|
||||
if (strlen(new_value) > MULTIPART_BUF_SIZE) {
|
||||
*error_msg = apr_psprintf(msr->mp, "Multipart: Part header too long.");
|
||||
return -1;
|
||||
}
|
||||
@ -858,8 +858,8 @@ int multipart_process_chunk(modsec_rec *msr, const char *buf,
|
||||
char c = *inptr;
|
||||
int process_buffer = 0;
|
||||
|
||||
if ((c == 0x0d)&&(msr->mpd->bufleft == 1)) {
|
||||
/* we don't want to take 0x0d as the last byte in the buffer */
|
||||
if ((c == '\r')&&(msr->mpd->bufleft == 1)) {
|
||||
/* we don't want to take \r as the last byte in the buffer */
|
||||
process_buffer = 1;
|
||||
} else {
|
||||
inptr++;
|
||||
@ -873,7 +873,7 @@ int multipart_process_chunk(modsec_rec *msr, const char *buf,
|
||||
/* until we either reach the end of the line
|
||||
* or the end of our internal buffer
|
||||
*/
|
||||
if ((c == 0x0a)||(msr->mpd->bufleft == 0)||(process_buffer)) {
|
||||
if ((c == '\n')||(msr->mpd->bufleft == 0)||(process_buffer)) {
|
||||
int processed_as_boundary = 0;
|
||||
|
||||
*(msr->mpd->bufptr) = 0;
|
||||
|
@ -9,9 +9,7 @@
|
||||
*
|
||||
*/
|
||||
#include "msc_parsers.h"
|
||||
#include "iconv.h"
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
/**
|
||||
*
|
||||
@ -307,6 +305,6 @@ void add_argument(modsec_rec *msr, apr_table_t *arguments, msc_arg *arg) {
|
||||
arg->origin, log_escape_ex(msr->mp, arg->name, arg->name_len),
|
||||
log_escape_ex(msr->mp, arg->value, arg->value_len));
|
||||
|
||||
apr_table_addn(arguments, arg->name, (void *)arg);
|
||||
apr_table_addn(arguments, log_escape_nq_ex(msr->mp, arg->name, arg->name_len), (void *)arg);
|
||||
}
|
||||
|
||||
|
@ -832,13 +832,13 @@ int urldecode_nonstrict_inplace_ex(unsigned char *input, long int input_len, int
|
||||
/* Not a valid encoding, skip this % */
|
||||
*d++ = input[i++];
|
||||
count ++;
|
||||
(*invalid_count)++; /* parens quiet compiler warning */
|
||||
(*invalid_count)++;
|
||||
}
|
||||
} else {
|
||||
/* Not enough bytes available, copy the raw bytes. */
|
||||
*d++ = input[i++];
|
||||
count ++;
|
||||
(*invalid_count)++; /* parens quiet compiler warning */
|
||||
(*invalid_count)++;
|
||||
}
|
||||
} else {
|
||||
/* Character is not a percent sign. */
|
||||
@ -1172,9 +1172,8 @@ int is_empty_string(const char *string) {
|
||||
unsigned int i;
|
||||
|
||||
if (string == NULL) return 1;
|
||||
if (strlen(string) == 0) return 1;
|
||||
|
||||
for(i = 0; i < strlen(string); i++) {
|
||||
for(i = 0; string[i] != '\0'; i++) {
|
||||
if (!isspace(string[i])) {
|
||||
return 0;
|
||||
}
|
||||
|
148
apache2/re.c
148
apache2/re.c
@ -14,6 +14,17 @@
|
||||
|
||||
#include "msc_lua.h"
|
||||
|
||||
static const char *const severities[] = {
|
||||
"EMERGENCY",
|
||||
"ALERT",
|
||||
"CRITICAL",
|
||||
"ERROR",
|
||||
"WARNING",
|
||||
"NOTICE",
|
||||
"INFO",
|
||||
"DEBUG",
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* -- Actions, variables, functions and operator functions ----------------- */
|
||||
|
||||
@ -198,7 +209,6 @@ msre_var *msre_create_var(msre_ruleset *ruleset, const char *name, const char *p
|
||||
if (var->metadata->validate != NULL) {
|
||||
*error_msg = var->metadata->validate(ruleset, var);
|
||||
if (*error_msg != NULL) {
|
||||
/* ENH Shouldn't we log the problem? */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -353,7 +363,6 @@ int msre_parse_generic(apr_pool_t *mp, const char *text, apr_table_t *vartable,
|
||||
|
||||
for(;;) {
|
||||
if (*p == '\0') {
|
||||
// TODO better 64-bit support here
|
||||
*error_msg = apr_psprintf(mp, "Missing closing quote at position %d: %s",
|
||||
(int)(p - text), text);
|
||||
free(value);
|
||||
@ -361,14 +370,13 @@ int msre_parse_generic(apr_pool_t *mp, const char *text, apr_table_t *vartable,
|
||||
} else
|
||||
if (*p == '\\') {
|
||||
if ( (*(p + 1) == '\0') || ((*(p + 1) != '\'')&&(*(p + 1) != '\\')) ) {
|
||||
// TODO better 64-bit support here
|
||||
*error_msg = apr_psprintf(mp, "Invalid quoted pair at position %d: %s",
|
||||
(int)(p - text), text);
|
||||
free(value);
|
||||
return -1;
|
||||
}
|
||||
p++;
|
||||
*d++ = *p++;
|
||||
*(d++) = *(p++);
|
||||
} else
|
||||
if (*p == '\'') {
|
||||
*d = '\0';
|
||||
@ -376,7 +384,7 @@ int msre_parse_generic(apr_pool_t *mp, const char *text, apr_table_t *vartable,
|
||||
break;
|
||||
}
|
||||
else {
|
||||
*d++ = *p++;
|
||||
*(d++) = *(p++);
|
||||
}
|
||||
}
|
||||
|
||||
@ -629,6 +637,61 @@ void msre_engine_destroy(msre_engine *engine) {
|
||||
* transaction phase.
|
||||
*/
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr) {
|
||||
apr_array_header_t *arr = NULL;
|
||||
msre_rule **rules = NULL;
|
||||
apr_status_t rc;
|
||||
apr_time_t time1;
|
||||
int i;
|
||||
|
||||
switch (msr->phase) {
|
||||
case PHASE_REQUEST_HEADERS :
|
||||
arr = ruleset->phase_request_headers;
|
||||
break;
|
||||
case PHASE_REQUEST_BODY :
|
||||
arr = ruleset->phase_request_body;
|
||||
break;
|
||||
case PHASE_RESPONSE_HEADERS :
|
||||
arr = ruleset->phase_response_headers;
|
||||
break;
|
||||
case PHASE_RESPONSE_BODY :
|
||||
arr = ruleset->phase_response_body;
|
||||
break;
|
||||
case PHASE_LOGGING :
|
||||
arr = ruleset->phase_logging;
|
||||
break;
|
||||
default :
|
||||
msr_log(msr, 1, "Internal Error: Invalid phase %d", msr->phase);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rules = (msre_rule **)arr->elts;
|
||||
for (i = 0; i < arr->nelts; i++) {
|
||||
msre_rule *rule = rules[i];
|
||||
rule->execution_time = 0;
|
||||
}
|
||||
|
||||
time1 = apr_time_now();
|
||||
|
||||
for (i = 0; i < 10000; i++) {
|
||||
rc = msre_ruleset_process_phase_(ruleset, msr);
|
||||
}
|
||||
|
||||
msr_log(msr, 1, "Phase %d: %" APR_TIME_T_FMT " usec", msr->phase, ((apr_time_now() - time1) / 10000));
|
||||
|
||||
rules = (msre_rule **)arr->elts;
|
||||
for (i = 0; i < arr->nelts; i++) {
|
||||
msre_rule *rule = rules[i];
|
||||
msr_log(msr, 1, "Rule %pp [id \"%s\"][file \"%s\"][line \"%d\"]: %lu usec", rule,
|
||||
((rule->actionset != NULL)&&(rule->actionset->id != NULL)) ? rule->actionset->id : "-",
|
||||
rule->filename != NULL ? rule->filename : "-",
|
||||
rule->line_num,
|
||||
(rule->execution_time / 10000));
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static apr_status_t msre_ruleset_process_phase_(msre_ruleset *ruleset, modsec_rec *msr) {
|
||||
#else
|
||||
apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr) {
|
||||
@ -905,66 +968,6 @@ apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
apr_status_t msre_ruleset_process_phase(msre_ruleset *ruleset, modsec_rec *msr) {
|
||||
apr_array_header_t *arr = NULL;
|
||||
msre_rule **rules = NULL;
|
||||
apr_status_t rc;
|
||||
apr_time_t time1;
|
||||
int i;
|
||||
|
||||
switch (msr->phase) {
|
||||
case PHASE_REQUEST_HEADERS :
|
||||
arr = ruleset->phase_request_headers;
|
||||
break;
|
||||
case PHASE_REQUEST_BODY :
|
||||
arr = ruleset->phase_request_body;
|
||||
break;
|
||||
case PHASE_RESPONSE_HEADERS :
|
||||
arr = ruleset->phase_response_headers;
|
||||
break;
|
||||
case PHASE_RESPONSE_BODY :
|
||||
arr = ruleset->phase_response_body;
|
||||
break;
|
||||
case PHASE_LOGGING :
|
||||
arr = ruleset->phase_logging;
|
||||
break;
|
||||
default :
|
||||
msr_log(msr, 1, "Internal Error: Invalid phase %d", msr->phase);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rules = (msre_rule **)arr->elts;
|
||||
for (i = 0; i < arr->nelts; i++) {
|
||||
msre_rule *rule = rules[i];
|
||||
rule->execution_time = 0;
|
||||
}
|
||||
|
||||
time1 = apr_time_now();
|
||||
|
||||
for (i = 0; i < 10000; i++) {
|
||||
rc = msre_ruleset_process_phase_(ruleset, msr);
|
||||
}
|
||||
|
||||
msr_log(msr, 1, "Phase %d: %" APR_TIME_T_FMT " usec", msr->phase, ((apr_time_now() - time1) / 10000));
|
||||
|
||||
rules = (msre_rule **)arr->elts;
|
||||
for (i = 0; i < arr->nelts; i++) {
|
||||
msre_rule *rule = rules[i];
|
||||
msr_log(msr, 1, "Rule %pp [id \"%s\"][file \"%s\"][line \"%d\"]: %u usec (trans:%u usec, op:%u usec)",
|
||||
rule,
|
||||
((rule->actionset != NULL)&&(rule->actionset->id != NULL)) ? rule->actionset->id : "-",
|
||||
rule->filename != NULL ? rule->filename : "-",
|
||||
rule->line_num,
|
||||
(rule->execution_time / 10000),
|
||||
(rule->trans_time / 10000),
|
||||
(rule->op_time / 10000));
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Creates a ruleset that will be handled by the default
|
||||
* implementation.
|
||||
@ -1120,18 +1123,6 @@ int msre_ruleset_rule_remove_with_exception(msre_ruleset *ruleset, rule_exceptio
|
||||
* Returns the name of the supplied severity level.
|
||||
*/
|
||||
static const char *msre_format_severity(int severity) {
|
||||
static const char *const severities[] = {
|
||||
"EMERGENCY",
|
||||
"ALERT",
|
||||
"CRITICAL",
|
||||
"ERROR",
|
||||
"WARNING",
|
||||
"NOTICE",
|
||||
"INFO",
|
||||
"DEBUG",
|
||||
NULL,
|
||||
};
|
||||
|
||||
if ((severity >= 0)&&(severity <= 7)) {
|
||||
return severities[severity];
|
||||
}
|
||||
@ -1623,10 +1614,11 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
const char *expnames = NULL;
|
||||
|
||||
arr = apr_table_elts(tartab);
|
||||
te = (apr_table_entry_t *)arr->elts;
|
||||
if (arr->nelts > 0) {
|
||||
te = (apr_table_entry_t *)arr->elts;
|
||||
expnames = apr_pstrdup(mptmp, ((msre_var *)te[0].val)->name);
|
||||
for(i = 1; i < arr->nelts; i++) {
|
||||
msr_log(msr, 4, "Combine %s|%s.", expnames, ((msre_var *)te[i].val)->name);
|
||||
expnames = apr_psprintf(mptmp, "%s|%s", expnames, ((msre_var *)te[i].val)->name);
|
||||
}
|
||||
if (strcmp(rule->p1, expnames) != 0) {
|
||||
|
@ -199,24 +199,11 @@ int expand_macros(modsec_rec *msr, msc_string *var, msre_rule *rule, apr_pool_t
|
||||
*q = '\0';
|
||||
}
|
||||
|
||||
/* ENH Do we want to support %{DIGIT} as well? */
|
||||
|
||||
next_text_start = t + 1; /* *t was '}' */
|
||||
} else {
|
||||
next_text_start = t; /* *t was '\0' */
|
||||
}
|
||||
}
|
||||
/* Removed %0-9 macros as it messes up urlEncoding in the match
|
||||
* where having '%0a' will be treated as %{TX.0}a, which is incorrect.
|
||||
* */
|
||||
#if 0
|
||||
else if ((*(p + 1) >= '0')&&(*(p + 1) <= '9')) {
|
||||
/* Special case for regex captures. */
|
||||
var_name = "TX";
|
||||
var_value = apr_pstrmemdup(mptmp, p + 1, 1);
|
||||
next_text_start = p + 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (var_name != NULL) {
|
||||
char *my_error_msg = NULL;
|
||||
@ -527,8 +514,6 @@ static char *msre_action_skipAfter_validate(msre_engine *engine, msre_action *ac
|
||||
static apr_status_t msre_action_skipAfter_init(msre_engine *engine, msre_actionset *actionset,
|
||||
msre_action *action)
|
||||
{
|
||||
// TODO: Need to keep track of skipAfter IDs so we can insert placeholders after
|
||||
// we get to the real rule with that ID.
|
||||
actionset->skip_after = action->param;
|
||||
return 1;
|
||||
}
|
||||
@ -728,12 +713,12 @@ static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
|
||||
msr->txcfg->is_enabled = MODSEC_ENABLED;
|
||||
msr->usercfg->is_enabled = MODSEC_ENABLED;
|
||||
}
|
||||
|
||||
else
|
||||
if (strcasecmp(value, "off") == 0) {
|
||||
msr->txcfg->is_enabled = MODSEC_DISABLED;
|
||||
msr->usercfg->is_enabled = MODSEC_DISABLED;
|
||||
}
|
||||
|
||||
else
|
||||
if (strcasecmp(value, "detectiononly") == 0) {
|
||||
msr->txcfg->is_enabled = MODSEC_DETECTION_ONLY;
|
||||
msr->usercfg->is_enabled = MODSEC_DETECTION_ONLY;
|
||||
@ -776,12 +761,12 @@ static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
|
||||
msr->txcfg->auditlog_flag = AUDITLOG_ON;
|
||||
msr->usercfg->auditlog_flag = AUDITLOG_ON;
|
||||
}
|
||||
|
||||
else
|
||||
if (strcasecmp(value, "off") == 0) {
|
||||
msr->txcfg->auditlog_flag = AUDITLOG_OFF;
|
||||
msr->usercfg->auditlog_flag = AUDITLOG_OFF;
|
||||
}
|
||||
|
||||
else
|
||||
if (strcasecmp(value, "relevantonly") == 0) {
|
||||
msr->txcfg->auditlog_flag = AUDITLOG_RELEVANT;
|
||||
msr->usercfg->auditlog_flag = AUDITLOG_RELEVANT;
|
||||
@ -811,7 +796,7 @@ static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
|
||||
|
||||
while(*s != '\0') {
|
||||
if (*s != c) {
|
||||
*d++ = *s++;
|
||||
*(d++) = *(s++);
|
||||
} else {
|
||||
s++;
|
||||
}
|
||||
@ -853,7 +838,8 @@ static apr_status_t msre_action_ctl_execute(modsec_rec *msr, apr_pool_t *mptmp,
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
/* ENH Should never happen, but log if it does. */
|
||||
/* Should never happen, but log if it does. */
|
||||
msr_log(msr, 1, "Internal Error: Unknown ctl action \"%s\".", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1082,8 +1068,9 @@ static apr_status_t msre_action_setvar_execute(modsec_rec *msr, apr_pool_t *mptm
|
||||
target_col = msr->tx_vars;
|
||||
s = strstr(var_name, ".");
|
||||
if (s == NULL) {
|
||||
/* ENH Log warning detected variable name but no collection. */
|
||||
return 0;
|
||||
msr_log(msr, 3, "Asked to set variable \"%s\", but no collection name specified. ",
|
||||
log_escape(msr->mp, var_name));
|
||||
return 0;
|
||||
}
|
||||
col_name = var_name;
|
||||
var_name = s + 1;
|
||||
@ -1225,12 +1212,13 @@ static apr_status_t msre_action_expirevar_execute(modsec_rec *msr, apr_pool_t *m
|
||||
|
||||
target_col = (apr_table_t *)apr_table_get(msr->collections, col_name);
|
||||
if (target_col == NULL) {
|
||||
msr_log(msr, 3, "Could not set variable \"%s.%s\" as the collection does not exist.",
|
||||
msr_log(msr, 3, "Could not expire variable \"%s.%s\" as the collection does not exist.",
|
||||
log_escape(msr->mp, col_name), log_escape(msr->mp, var_name));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* ENH Log warning detected variable name but no collection. */
|
||||
msr_log(msr, 3, "Asked to expire variable \"%s\", but no collection name specified. ",
|
||||
log_escape(msr->mp, var_name));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1294,14 +1282,15 @@ static apr_status_t msre_action_deprecatevar_execute(modsec_rec *msr, apr_pool_t
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* ENH Log warning detected variable name but no collection. */
|
||||
msr_log(msr, 3, "Asked to deprecate variable \"%s\", but no collection name specified. ",
|
||||
log_escape(msr->mp, var_name));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find the current value. */
|
||||
var = (msc_string *)apr_table_get(target_col, var_name);
|
||||
if (var == NULL) {
|
||||
msr_log(msr, 9, "Asked to deprecate variable \"%s.%s\" but it does not exist.",
|
||||
msr_log(msr, 9, "Asked to deprecate variable \"%s.%s\", but it does not exist.",
|
||||
log_escape(msr->mp, col_name), log_escape(msr->mp, var_name));
|
||||
return 0;
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ static int msre_op_pmFromFile_param_init(msre_rule *rule, char **error_msg) {
|
||||
if (*fn == '\0') break;
|
||||
next = fn;
|
||||
while((isspace(*next) == 0) && (*next != '\0')) next++;
|
||||
while((isspace(*next) != 0) && (*next != '\0')) *next++ = '\0';
|
||||
while((isspace(*next) != 0) && (*next != '\0')) *(next++) = '\0';
|
||||
|
||||
/* Add path of the rule filename for a relative phrase filename */
|
||||
filepath = fn;
|
||||
@ -1114,17 +1114,22 @@ static int msre_op_geoLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
const char *geo_host = var->value;
|
||||
msc_string *s = NULL;
|
||||
int rc;
|
||||
|
||||
*error_msg = NULL;
|
||||
|
||||
if (geo == NULL) {
|
||||
msr_log(msr, 1, "Geo lookup for \"%s\" attempted without a database. Set SecGeoLookupDB.", geo_host);
|
||||
msr_log(msr, 1, "Geo lookup for \"%s\" attempted without a database. Set SecGeoLookupDB.", log_escape_nq(msr->mp, geo_host));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
rc = geo_lookup(msr, &rec, geo_host, error_msg);
|
||||
if (rc <= 0) {
|
||||
*error_msg = apr_psprintf(msr->mp, "Geo lookup for \"%s\" failed at %s.", log_escape_nq(msr->mp, geo_host), var->name);
|
||||
return rc;
|
||||
}
|
||||
*error_msg = apr_psprintf(msr->mp, "Geo lookup for \"%s\" succeeded at %s.",
|
||||
log_escape_nq(msr->mp, geo_host), var->name);
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "GEO: %s={country_code=%s, country_code3=%s, country_name=%s, country_continent=%s, region=%s, city=%s, postal_code=%s, latitude=%f, longitude=%f, dma_code=%d, area_code=%d}",
|
||||
@ -1144,54 +1149,63 @@ static int msre_op_geoLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
|
||||
s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
s->name = apr_pstrdup(msr->mp, "country_code");
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_pstrdup(msr->mp, rec.country_code ? rec.country_code : "");
|
||||
s->value_len = strlen(s->value);
|
||||
apr_table_setn(msr->geo_vars, s->name, (void *)s);
|
||||
|
||||
s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
s->name = apr_pstrdup(msr->mp, "country_code3");
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_pstrdup(msr->mp, rec.country_code3 ? rec.country_code3 : "");
|
||||
s->value_len = strlen(s->value);
|
||||
apr_table_setn(msr->geo_vars, s->name, (void *)s);
|
||||
|
||||
s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
s->name = apr_pstrdup(msr->mp, "region");
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_pstrdup(msr->mp, rec.region ? rec.region : "");
|
||||
s->value_len = strlen(s->value);
|
||||
apr_table_setn(msr->geo_vars, s->name, (void *)s);
|
||||
|
||||
s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
s->name = apr_pstrdup(msr->mp, "city");
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_pstrdup(msr->mp, rec.city ? rec.city : "");
|
||||
s->value_len = strlen(s->value);
|
||||
apr_table_setn(msr->geo_vars, s->name, (void *)s);
|
||||
|
||||
s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
s->name = apr_pstrdup(msr->mp, "postal_code");
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_pstrdup(msr->mp, rec.postal_code ? rec.postal_code : "");
|
||||
s->value_len = strlen(s->value);
|
||||
apr_table_setn(msr->geo_vars, s->name, (void *)s);
|
||||
|
||||
s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
s->name = apr_pstrdup(msr->mp, "latitude");
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_psprintf(msr->mp, "%f", rec.latitude);
|
||||
s->value_len = strlen(s->value);
|
||||
apr_table_setn(msr->geo_vars, s->name, (void *)s);
|
||||
|
||||
s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
s->name = apr_pstrdup(msr->mp, "longitude");
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_psprintf(msr->mp, "%f", rec.longitude);
|
||||
s->value_len = strlen(s->value);
|
||||
apr_table_setn(msr->geo_vars, s->name, (void *)s);
|
||||
|
||||
s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
s->name = apr_pstrdup(msr->mp, "dma_code");
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_psprintf(msr->mp, "%d", rec.dma_code);
|
||||
s->value_len = strlen(s->value);
|
||||
apr_table_setn(msr->geo_vars, s->name, (void *)s);
|
||||
|
||||
s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
s->name = apr_pstrdup(msr->mp, "area_code");
|
||||
s->name_len = strlen(s->name);
|
||||
s->value = apr_psprintf(msr->mp, "%d", rec.area_code);
|
||||
s->value_len = strlen(s->value);
|
||||
apr_table_setn(msr->geo_vars, s->name, (void *)s);
|
||||
@ -1230,12 +1244,12 @@ static int msre_op_rbl_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
rc = apr_sockaddr_info_get(&sa, name_to_check,
|
||||
APR_UNSPEC/*msr->r->connection->remote_addr->family*/, 0, 0, msr->mp);
|
||||
if (rc == APR_SUCCESS) {
|
||||
*error_msg = apr_psprintf(msr->r->pool, "RBL lookup of %s succeeded.",
|
||||
log_escape_nq(msr->mp, name_to_check));
|
||||
*error_msg = apr_psprintf(msr->r->pool, "RBL lookup of %s succeeded at %s.",
|
||||
log_escape_nq(msr->mp, name_to_check), var->name);
|
||||
return 1; /* Match. */
|
||||
}
|
||||
|
||||
msr_log(msr, 5, "RBL lookup of %s failed.", log_escape_nq(msr->mp, name_to_check));
|
||||
msr_log(msr, 5, "RBL lookup of %s failed at %s.", log_escape_nq(msr->mp, name_to_check), var->name);
|
||||
|
||||
/* No match. */
|
||||
return 0;
|
||||
@ -1256,8 +1270,7 @@ static int msre_op_inspectFile_init(msre_rule *rule, char **error_msg) {
|
||||
|
||||
filename = resolve_relative_path(rule->ruleset->mp, rule->filename, filename);
|
||||
|
||||
#ifdef WITH_LUA
|
||||
// TODO Write & use string_ends(s, e).
|
||||
/* ENH Write & use string_ends(s, e). */
|
||||
if (strlen(rule->op_param) > 4) {
|
||||
char *p = filename + strlen(filename) - 4;
|
||||
if ((p[0] == '.')&&(p[1] == 'l')&&(p[2] == 'u')&&(p[3] == 'a'))
|
||||
@ -1271,11 +1284,11 @@ static int msre_op_inspectFile_init(msre_rule *rule, char **error_msg) {
|
||||
rule->op_param_data = script;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rule->op_param_data == NULL) {
|
||||
// TODO Verify the script exists and that we have
|
||||
// the rights to execute it.
|
||||
/* ENH Verify the script exists and that we have
|
||||
* the rights to execute it.
|
||||
*/
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -1481,6 +1494,7 @@ static int msre_op_validateUrlEncoding_execute(modsec_rec *msr, msre_rule *rule,
|
||||
switch(rc) {
|
||||
case 1 :
|
||||
/* Encoding is valid */
|
||||
*error_msg = apr_psprintf(msr->mp, "Valid URL Encoding at %s.", var->name);
|
||||
break;
|
||||
case -2 :
|
||||
*error_msg = apr_psprintf(msr->mp, "Invalid URL Encoding: Non-hexadecimal "
|
||||
@ -1677,7 +1691,7 @@ static int msre_op_eq_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
*error_msg = apr_psprintf(msr->mp, "Operator EQ match: %d.", right);
|
||||
*error_msg = apr_psprintf(msr->mp, "Operator EQ matched %d at %s.", right, var->name);
|
||||
/* Match. */
|
||||
return 1;
|
||||
}
|
||||
@ -1706,7 +1720,7 @@ static int msre_op_gt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
*error_msg = apr_psprintf(msr->mp, "Operator GT match: %d.", right);
|
||||
*error_msg = apr_psprintf(msr->mp, "Operator GT matched %d at %s.", right, var->name);
|
||||
/* Match. */
|
||||
return 1;
|
||||
}
|
||||
@ -1735,7 +1749,7 @@ static int msre_op_lt_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
*error_msg = apr_psprintf(msr->mp, "Operator LT match: %d.", right);
|
||||
*error_msg = apr_psprintf(msr->mp, "Operator LT matched %d at %s.", right, var->name);
|
||||
/* Match. */
|
||||
return 1;
|
||||
}
|
||||
@ -1764,7 +1778,7 @@ static int msre_op_ge_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
*error_msg = apr_psprintf(msr->mp, "Operator GE match: %d.", right);
|
||||
*error_msg = apr_psprintf(msr->mp, "Operator GE matched %d at %s.", right, var->name);
|
||||
/* Match. */
|
||||
return 1;
|
||||
}
|
||||
@ -1793,7 +1807,7 @@ static int msre_op_le_execute(modsec_rec *msr, msre_rule *rule, msre_var *var,
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
*error_msg = apr_psprintf(msr->mp, "Operator LE match: %d.", right);
|
||||
*error_msg = apr_psprintf(msr->mp, "Operator LE matched %d at %s.", right, var->name);
|
||||
/* Match. */
|
||||
return 1;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ static int var_args_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
|
||||
rvar->value = arg->value;
|
||||
rvar->value_len = arg->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS:%s", log_escape_nq(mptmp, arg->name));
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -186,7 +186,7 @@ static int var_args_names_generate(modsec_rec *msr, msre_var *var, msre_rule *ru
|
||||
|
||||
rvar->value = arg->name;
|
||||
rvar->value_len = arg->name_len;
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS_NAMES:%s", log_escape_nq(mptmp, arg->name));
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS_NAMES:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -234,7 +234,7 @@ static int var_args_get_generate(modsec_rec *msr, msre_var *var, msre_rule *rule
|
||||
|
||||
rvar->value = arg->value;
|
||||
rvar->value_len = arg->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS_GET:%s", log_escape_nq(mptmp, arg->name));
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS_GET:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -280,7 +280,7 @@ static int var_args_get_names_generate(modsec_rec *msr, msre_var *var, msre_rule
|
||||
|
||||
rvar->value = arg->name;
|
||||
rvar->value_len = arg->name_len;
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS_GET_NAMES:%s", log_escape_nq(mptmp, arg->name));
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS_GET_NAMES:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -328,7 +328,7 @@ static int var_args_post_generate(modsec_rec *msr, msre_var *var, msre_rule *rul
|
||||
|
||||
rvar->value = arg->value;
|
||||
rvar->value_len = arg->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS_POST:%s", log_escape_nq(mptmp, arg->name));
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS_POST:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -374,7 +374,7 @@ static int var_args_post_names_generate(modsec_rec *msr, msre_var *var, msre_rul
|
||||
|
||||
rvar->value = arg->name;
|
||||
rvar->value_len = arg->name_len;
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS_POST_NAMES:%s", log_escape_nq(mptmp, arg->name));
|
||||
rvar->name = apr_psprintf(mptmp, "ARGS_POST_NAMES:%s", log_escape_nq_ex(mptmp, arg->name, arg->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -722,7 +722,7 @@ static int var_tx_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
|
||||
rvar->value = str->value;
|
||||
rvar->value_len = str->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "TX:%s", log_escape_nq(mptmp, str->name));
|
||||
rvar->name = apr_psprintf(mptmp, "TX:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -766,7 +766,7 @@ static int var_geo_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
|
||||
rvar->value = str->value;
|
||||
rvar->value_len = str->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "GEO:%s", log_escape_nq(mptmp, str->name));
|
||||
rvar->name = apr_psprintf(mptmp, "GEO:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -823,7 +823,7 @@ static int var_ip_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
|
||||
rvar->value = str->value;
|
||||
rvar->value_len = str->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "IP:%s", log_escape_nq(mptmp, str->name));
|
||||
rvar->name = apr_psprintf(mptmp, "IP:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -839,10 +839,10 @@ static int var_matched_var_generate(modsec_rec *msr, msre_var *var, msre_rule *r
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
return var_simple_generate_ex(var, vartab, mptmp,
|
||||
apr_pmemdup(mptmp,
|
||||
msr->matched_var->value,
|
||||
msr->matched_var->value_len),
|
||||
msr->matched_var->value_len);
|
||||
apr_pmemdup(mptmp,
|
||||
msr->matched_var->value,
|
||||
msr->matched_var->value_len),
|
||||
msr->matched_var->value_len);
|
||||
}
|
||||
|
||||
/* MATCHED_VAR_NAME */
|
||||
@ -851,10 +851,10 @@ static int var_matched_var_name_generate(modsec_rec *msr, msre_var *var, msre_ru
|
||||
apr_table_t *vartab, apr_pool_t *mptmp)
|
||||
{
|
||||
return var_simple_generate_ex(var, vartab, mptmp,
|
||||
apr_pmemdup(mptmp,
|
||||
msr->matched_var->name,
|
||||
msr->matched_var->name_len),
|
||||
msr->matched_var->name_len);
|
||||
apr_pmemdup(mptmp,
|
||||
msr->matched_var->name,
|
||||
msr->matched_var->name_len),
|
||||
msr->matched_var->name_len);
|
||||
}
|
||||
|
||||
/* SESSION */
|
||||
@ -895,7 +895,7 @@ static int var_session_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
|
||||
rvar->value = str->value;
|
||||
rvar->value_len = str->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "SESSION:%s", log_escape_nq(mptmp, str->name));
|
||||
rvar->name = apr_psprintf(mptmp, "SESSION:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -943,7 +943,7 @@ static int var_user_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
|
||||
rvar->value = str->value;
|
||||
rvar->value_len = str->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "USER:%s", log_escape_nq(mptmp, str->name));
|
||||
rvar->name = apr_psprintf(mptmp, "USER:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -991,7 +991,7 @@ static int var_global_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
|
||||
rvar->value = str->value;
|
||||
rvar->value_len = str->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "GLOBAL:%s", log_escape_nq(mptmp, str->name));
|
||||
rvar->name = apr_psprintf(mptmp, "GLOBAL:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -1039,7 +1039,7 @@ static int var_resource_generate(modsec_rec *msr, msre_var *var, msre_rule *rule
|
||||
|
||||
rvar->value = str->value;
|
||||
rvar->value_len = str->value_len;
|
||||
rvar->name = apr_psprintf(mptmp, "RESOURCE:%s", log_escape_nq(mptmp, str->name));
|
||||
rvar->name = apr_psprintf(mptmp, "RESOURCE:%s", log_escape_nq_ex(mptmp, str->name, str->name_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -1202,7 +1202,7 @@ static int var_files_names_generate(modsec_rec *msr, msre_var *var, msre_rule *r
|
||||
rvar->value = parts[i]->name;
|
||||
rvar->value_len = strlen(rvar->value);
|
||||
rvar->name = apr_psprintf(mptmp, "FILES_NAMES:%s",
|
||||
log_escape_nq(mptmp, parts[i]->name));
|
||||
log_escape_nq_ex(mptmp, parts[i]->name, rvar->value_len));
|
||||
apr_table_addn(vartab, rvar->name, (void *)rvar);
|
||||
|
||||
count++;
|
||||
@ -2208,7 +2208,7 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
0, 1,
|
||||
var_env_validate,
|
||||
var_env_generate,
|
||||
VAR_CACHE,
|
||||
VAR_DONT_CACHE,
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
@ -2274,7 +2274,7 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
1, 1,
|
||||
var_generic_list_validate,
|
||||
var_geo_generate,
|
||||
VAR_CACHE,
|
||||
VAR_DONT_CACHE,
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
@ -2285,7 +2285,7 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
1, 1,
|
||||
var_generic_list_validate,
|
||||
var_global_generate,
|
||||
VAR_CACHE,
|
||||
VAR_DONT_CACHE,
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
@ -2307,7 +2307,7 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
1, 1,
|
||||
var_generic_list_validate,
|
||||
var_ip_generate,
|
||||
VAR_CACHE,
|
||||
VAR_DONT_CACHE,
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
@ -2538,7 +2538,7 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
1, 1,
|
||||
var_generic_list_validate,
|
||||
var_resource_generate,
|
||||
VAR_CACHE,
|
||||
VAR_DONT_CACHE,
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
@ -2912,7 +2912,7 @@ void msre_engine_register_default_variables(msre_engine *engine) {
|
||||
1, 1,
|
||||
var_generic_list_validate,
|
||||
var_session_generate,
|
||||
VAR_CACHE,
|
||||
VAR_DONT_CACHE,
|
||||
PHASE_REQUEST_HEADERS
|
||||
);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user