Merge 2.5.x changes into trunk.

This commit is contained in:
b1v1r 2009-08-12 23:03:11 +00:00
parent 155608be35
commit 7379a4fb3f
9 changed files with 254 additions and 21 deletions

10
CHANGES
View File

@ -1,5 +1,11 @@
27 July 2009 - trunk 12 Aug 2009 - trunk
-------------------- -------------------
* Fixed crash on configuration if SecMarker is used before any rules.
* Fixed SecRuleUpdateActionById so that it will work on chain starters.
* Cleanup build system for mlogc.
* Allow mlogc to periodically flush memory pools. * Allow mlogc to periodically flush memory pools.

View File

@ -565,6 +565,11 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
msre_rule *rule = NULL; msre_rule *rule = NULL;
extern msc_engine *modsecurity; 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. */ /* Create a ruleset if one does not exist. */
if ((dcfg->ruleset == NULL)||(dcfg->ruleset == NOT_SET_P)) { if ((dcfg->ruleset == NULL)||(dcfg->ruleset == NOT_SET_P)) {
dcfg->ruleset = msre_ruleset_create(modsecurity->msre, cmd->pool); dcfg->ruleset = msre_ruleset_create(modsecurity->msre, cmd->pool);
@ -698,7 +703,7 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
#ifdef DEBUG_CONF #ifdef DEBUG_CONF
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool, ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
"Adding rule %pp id=\"%s\".", rule, (rule->actionset->id == NOT_SET_P "Adding rule %pp phase=%d id=\"%s\".", rule, rule->actionset->phase, (rule->actionset->id == NOT_SET_P
? "(none)" : rule->actionset->id)); ? "(none)" : rule->actionset->id));
#endif #endif
@ -749,6 +754,11 @@ static const char *add_marker(cmd_parms *cmd, directory_config *dcfg, const char
extern msc_engine *modsecurity; extern msc_engine *modsecurity;
int p; 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. */ /* Create a ruleset if one does not exist. */
if ((dcfg->ruleset == NULL)||(dcfg->ruleset == NOT_SET_P)) { if ((dcfg->ruleset == NULL)||(dcfg->ruleset == NOT_SET_P)) {
dcfg->ruleset = msre_ruleset_create(modsecurity->msre, cmd->pool); dcfg->ruleset = msre_ruleset_create(modsecurity->msre, cmd->pool);
@ -766,13 +776,21 @@ static const char *add_marker(cmd_parms *cmd, directory_config *dcfg, const char
/* Add placeholder to each phase */ /* Add placeholder to each phase */
for (p = PHASE_FIRST; p <= PHASE_LAST; p++) { 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) { if (msre_ruleset_rule_add(dcfg->ruleset, rule, p) < 0) {
return "Internal Error: Failed to add marker to the ruleset."; return "Internal Error: Failed to add marker to the ruleset.";
} }
} }
/* No longer need to search for the ID */ /* No longer need to search for the ID */
apr_table_unset(dcfg->tmp_rule_placeholders, rule->actionset->id); if (dcfg->tmp_rule_placeholders != NULL) {
apr_table_unset(dcfg->tmp_rule_placeholders, rule->actionset->id);
}
return NULL; return NULL;
} }

151
apache2/configure vendored
View File

@ -701,6 +701,7 @@ CPPFLAGS
LDFLAGS LDFLAGS
CXXFLAGS CXXFLAGS
CXX CXX
AWK
target_alias target_alias
host_alias host_alias
build_alias build_alias
@ -1897,6 +1898,48 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
# Checks for programs. # Checks for programs.
for ac_prog in gawk mawk nawk awk
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if test "${ac_cv_prog_AWK+set}" = set; then
$as_echo_n "(cached) " >&6
else
if test -n "$AWK"; then
ac_cv_prog_AWK="$AWK" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_prog_AWK="$ac_prog"
$as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
AWK=$ac_cv_prog_AWK
if test -n "$AWK"; then
{ $as_echo "$as_me:$LINENO: result: $AWK" >&5
$as_echo "$AWK" >&6; }
else
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$AWK" && break
done
ac_ext=cpp ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS' ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@ -4549,6 +4592,110 @@ _ACEOF
;; ;;
esac esac
{ $as_echo "$as_me:$LINENO: checking for pid_t" >&5
$as_echo_n "checking for pid_t... " >&6; }
if test "${ac_cv_type_pid_t+set}" = set; then
$as_echo_n "(cached) " >&6
else
ac_cv_type_pid_t=no
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
if (sizeof (pid_t))
return 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
$as_echo "$ac_try_echo") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
if (sizeof ((pid_t)))
return 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
$as_echo "$ac_try_echo") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
:
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_type_pid_t=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
$as_echo "$ac_cv_type_pid_t" >&6; }
if test "x$ac_cv_type_pid_t" = x""yes; then
:
else
cat >>confdefs.h <<_ACEOF
#define pid_t int
_ACEOF
fi
{ $as_echo "$as_me:$LINENO: checking for size_t" >&5 { $as_echo "$as_me:$LINENO: checking for size_t" >&5
$as_echo_n "checking for size_t... " >&6; } $as_echo_n "checking for size_t... " >&6; }
if test "${ac_cv_type_size_t+set}" = set; then if test "${ac_cv_type_size_t+set}" = set; then
@ -5138,7 +5285,8 @@ esac
for ac_func in atexit fchmod getcwd memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol
for ac_func in atexit fchmod getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol
do do
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
@ -6708,6 +6856,7 @@ gives unlimited permission to copy, distribute and modify it."
ac_pwd='$ac_pwd' ac_pwd='$ac_pwd'
srcdir='$srcdir' srcdir='$srcdir'
INSTALL='$INSTALL' INSTALL='$INSTALL'
AWK='$AWK'
test -n "\$AWK" || AWK=awk test -n "\$AWK" || AWK=awk
_ACEOF _ACEOF

View File

@ -4,15 +4,16 @@ dnl
dnl Use ./buildconf to produce a configure script dnl Use ./buildconf to produce a configure script
dnl dnl
AC_PREREQ(2.50) AC_PREREQ(2.63)
AC_INIT() AC_INIT
dnl AC_INIT(ModSecurity, 2.5, mod-security-users@lists.sourceforge.net, modsecurity-apache) dnl AC_INIT(ModSecurity, 2.5, mod-security-users@lists.sourceforge.net, modsecurity-apache)
AC_CONFIG_SRCDIR([mod_security2.c]) AC_CONFIG_SRCDIR([mod_security2.c])
AC_CONFIG_HEADER([mod_security2_config.h]) AC_CONFIG_HEADER([mod_security2_config.h])
AC_CONFIG_AUX_DIR([build]) AC_CONFIG_AUX_DIR([build])
# Checks for programs. # Checks for programs.
AC_PROG_AWK
AC_PROG_CXX AC_PROG_CXX
AC_PROG_CC AC_PROG_CC
AC_PROG_CPP AC_PROG_CPP
@ -32,6 +33,7 @@ AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h unistd.h])
AC_C_CONST AC_C_CONST
AC_C_INLINE AC_C_INLINE
AC_C_RESTRICT AC_C_RESTRICT
AC_TYPE_PID_T
AC_TYPE_SIZE_T AC_TYPE_SIZE_T
AC_STRUCT_TM AC_STRUCT_TM
AC_TYPE_UINT8_T AC_TYPE_UINT8_T
@ -39,7 +41,7 @@ AC_TYPE_UINT8_T
# Checks for library functions. # Checks for library functions.
AC_FUNC_MALLOC AC_FUNC_MALLOC
AC_FUNC_MEMCMP AC_FUNC_MEMCMP
AC_CHECK_FUNCS([atexit fchmod getcwd memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol]) AC_CHECK_FUNCS([atexit fchmod getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol])
# Some directories # Some directories
MSC_BASE_DIR=`pwd` MSC_BASE_DIR=`pwd`

View File

@ -10,7 +10,7 @@ srclibdir = $(srcdir)/srclib
MLOGC_VERSION = `grep '^\#define *VERSION ' mlogc.c | sed 's/.*VERSION *"\([^"]*\)"/\1/'` MLOGC_VERSION = `grep '^\#define *VERSION ' mlogc.c | sed 's/.*VERSION *"\([^"]*\)"/\1/'`
APR_FLAGS = @APR_CFLAGS@ APR_FLAGS = @APR_CFLAGS@
APR_LIBS = @APR_LINK_LD@ APR_LIBS = @APR_LINK_LD@ @APR_LIBS@
CURL_FLAGS = @CURL_CFLAGS@ CURL_FLAGS = @CURL_CFLAGS@
CURL_LIBS = @CURL_LIBS@ CURL_LIBS = @CURL_LIBS@

View File

@ -22,6 +22,9 @@
to 0 otherwise. */ to 0 otherwise. */
#undef HAVE_MALLOC #undef HAVE_MALLOC
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
/* Define to 1 if you have the <memory.h> header file. */ /* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H #undef HAVE_MEMORY_H
@ -111,6 +114,9 @@
/* Define to rpl_malloc if the replacement function should be used. */ /* Define to rpl_malloc if the replacement function should be used. */
#undef malloc #undef malloc
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to the equivalent of the C99 'restrict' keyword, or to /* Define to the equivalent of the C99 'restrict' keyword, or to
nothing if this is not supported. Do not define if restrict is nothing if this is not supported. Do not define if restrict is
supported directly. */ supported directly. */

View File

@ -1188,8 +1188,9 @@ static msre_rule * msre_ruleset_fetch_phase_rule(const msre_ruleset *ruleset, co
for (i = 0; i < phase_arr->nelts; i++) { for (i = 0; i < phase_arr->nelts; i++) {
msre_rule *rule = (msre_rule *)rules[i]; msre_rule *rule = (msre_rule *)rules[i];
/* Rule with an action, not a sub-rule (chain) and a matching id */
if ( (rule->actionset != NULL) if ( (rule->actionset != NULL)
&& !rule->actionset->is_chained && (!rule->actionset->is_chained || !rule->chain_starter)
&& (rule->actionset->id != NULL) && (rule->actionset->id != NULL)
&& (strcmp(rule->actionset->id, id) == 0)) && (strcmp(rule->actionset->id, id) == 0))
{ {

View File

@ -1,10 +1,8 @@
### Tests for rule exceptions ### Tests for rule exceptions
# SecRuleRemoveByMsg
# SecRuleRemoveById # SecRuleRemoveById
{ {
type => "config", type => "rule",
comment => "SecRuleRemoveById (single)", comment => "SecRuleRemoveById (single)",
conf => qq( conf => qq(
SecRuleEngine On SecRuleEngine On
@ -27,7 +25,7 @@
), ),
}, },
{ {
type => "config", type => "rule",
comment => "SecRuleRemoveById (multiple)", comment => "SecRuleRemoveById (multiple)",
conf => qq( conf => qq(
SecRuleEngine On SecRuleEngine On
@ -52,7 +50,7 @@
), ),
}, },
{ {
type => "config", type => "rule",
comment => "SecRuleRemoveById (range)", comment => "SecRuleRemoveById (range)",
conf => qq( conf => qq(
SecRuleEngine On SecRuleEngine On
@ -77,7 +75,7 @@
), ),
}, },
{ {
type => "config", type => "rule",
comment => "SecRuleRemoveById (multiple + range)", comment => "SecRuleRemoveById (multiple + range)",
conf => qq( conf => qq(
SecRuleEngine On SecRuleEngine On
@ -105,7 +103,7 @@
# SecRuleRemoveByMsg # SecRuleRemoveByMsg
{ {
type => "config", type => "rule",
comment => "SecRuleRemoveByMsg", comment => "SecRuleRemoveByMsg",
conf => qq( conf => qq(
SecRuleEngine On SecRuleEngine On
@ -127,3 +125,52 @@
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
), ),
}, },
# SecRuleUpdateActionById
{
type => "rule",
comment => "SecRuleUpdateActionById",
conf => qq(
SecRuleEngine On
SecDebugLog $ENV{DEBUG_LOG}
SecDebugLogLevel 9
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:1,msg:'testing rule'"
SecRuleUpdateActionById 1 "pass,nolog"
),
match_log => {
-error => [ qr/ModSecurity: /, 1 ],
-audit => [ qr/./, 1 ],
debug => [ qr/id:1,.*,pass,nolog/, 1 ],
-debug => [ qr/Access denied/, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "rule",
comment => "SecRuleUpdateActionById (chain)",
conf => qq(
SecRuleEngine On
SecDebugLog $ENV{DEBUG_LOG}
SecDebugLogLevel 9
SecRule REQUEST_URI "test" "phase:1,deny,status:500,id:1,msg:'testing rule',chain"
SecRule ARGS "bar"
SecRuleUpdateActionById 1 "pass,nolog"
),
match_log => {
-error => [ qr/ModSecurity: /, 1 ],
-audit => [ qr/./, 1 ],
debug => [ qr/id:1,.*,pass,nolog/, 1 ],
-debug => [ qr/Access denied/, 1 ],
},
match_response => {
status => qr/^200$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?foo=bar",
),
},

View File

@ -6,7 +6,7 @@
Manual</title> Manual</title>
<articleinfo> <articleinfo>
<releaseinfo>Version 2.6.0-trunk (July 27, 2009)</releaseinfo> <releaseinfo>Version 2.6.0-trunk (Aug 12, 2009)</releaseinfo>
<copyright> <copyright>
<year>2004-2009</year> <year>2004-2009</year>
@ -533,7 +533,7 @@ LoadFile /usr/lib/liblua5.1.so</programlisting></para>
<para><emphasis>Example Usage:</emphasis> <literal <para><emphasis>Example Usage:</emphasis> <literal
moreinfo="none">SecAction moreinfo="none">SecAction
nolog,initcol:RESOURCE=%{REQUEST_FILENAME}</literal></para> nolog,phase:1,initcol:RESOURCE=%{REQUEST_FILENAME}</literal></para>
<para><emphasis>Processing Phase:</emphasis> Any</para> <para><emphasis>Processing Phase:</emphasis> Any</para>
@ -4753,10 +4753,14 @@ setvar:session.suspicious=1,<emphasis>expirevar:session.suspicious=3600</emphasi
<para>Example: The following example initiates IP address <para>Example: The following example initiates IP address
tracking.</para> tracking.</para>
<programlisting format="linespecific">SecAction<emphasis> initcol:ip=%{REMOTE_ADDR}</emphasis>,nolog</programlisting> <programlisting format="linespecific">SecAction <emphasis>phase:1,initcol:ip=%{REMOTE_ADDR}</emphasis>,nolog</programlisting>
<para><emphasis>Note</emphasis></para> <para><emphasis>Note</emphasis></para>
<para>Normally you will want to use <emphasis>phase:1</emphasis>
along with <emphasis>initcol</emphasis> so that the collection is
available in all phases.</para>
<para>Collections are loaded into memory when the initcol action is <para>Collections are loaded into memory when the initcol action is
encountered. The collection in storage will be persisted (and the encountered. The collection in storage will be persisted (and the
appropriate counters increased) <emphasis>only</emphasis> if it was appropriate counters increased) <emphasis>only</emphasis> if it was
@ -4775,7 +4779,7 @@ setvar:session.suspicious=1,<emphasis>expirevar:session.suspicious=3600</emphasi
<para>Example:</para> <para>Example:</para>
<programlisting format="linespecific">SecAction initcol:ip=%{REMOTE_ADDR},<emphasis>log</emphasis></programlisting> <programlisting format="linespecific">SecAction phase:1,initcol:ip=%{REMOTE_ADDR},<emphasis>log</emphasis></programlisting>
<para><emphasis>Note</emphasis></para> <para><emphasis>Note</emphasis></para>