Merge 2.5.x changes to trunk.

This commit is contained in:
b1v1r 2009-05-31 08:45:50 +00:00
parent 12b9bcd33a
commit e5becf8407
9 changed files with 240 additions and 98 deletions

View File

@ -1,6 +1,11 @@
20 May 2009 - trunk 31 May 2009 - trunk
------------------- -------------------
* Removed extra newline from audit log message line when logging XML errors.
This was causing problems parsing audit logs.
* Fixed @pm/@pmFromFile case insensitivity.
* Truncate long parameters in log message for "Match of ... against ... * Truncate long parameters in log message for "Match of ... against ...
required" messages. required" messages.

View File

@ -782,6 +782,9 @@ apr_status_t acmp_process_quick(ACMPT *acmpt, const char **match, const char *da
while (data < end) { while (data < end) {
acmp_utf8_char_t letter = (unsigned char)*data++; acmp_utf8_char_t letter = (unsigned char)*data++;
if (parser->is_case_sensitive == 0) letter = utf8_lcase(letter);
go_to = NULL; go_to = NULL;
while (go_to == NULL) { while (go_to == NULL) {
go_to = acmp_goto(node, letter); go_to = acmp_goto(node, letter);

View File

@ -236,7 +236,6 @@ void internal_log(request_rec *r, directory_config *dcfg, modsec_rec *msr,
apr_size_t nbytes, nbytes_written; apr_size_t nbytes, nbytes_written;
apr_file_t *debuglog_fd = NULL; apr_file_t *debuglog_fd = NULL;
int filter_debug_level = 0; int filter_debug_level = 0;
int str2len;
char str1[1024] = ""; char str1[1024] = "";
char str2[1256] = ""; char str2[1256] = "";
@ -257,20 +256,16 @@ void internal_log(request_rec *r, directory_config *dcfg, modsec_rec *msr,
*/ */
if ((level > 3)&&( (debuglog_fd == NULL) || (level > filter_debug_level) )) return; if ((level > 3)&&( (debuglog_fd == NULL) || (level > filter_debug_level) )) return;
/* Construct the message (leaving a byte left for a newline if needed). */ /* Construct the message. */
apr_vsnprintf(str1, sizeof(str1), text, ap); apr_vsnprintf(str1, sizeof(str1), text, ap);
str2len = apr_snprintf(str2, sizeof(str2) - 1,
"[%s] [%s/sid#%pp][rid#%pp][%s][%d] %s", /* Construct the log entry. */
apr_snprintf(str2, sizeof(str2),
"[%s] [%s/sid#%pp][rid#%pp][%s][%d] %s\n",
current_logtime(msr->mp), ap_get_server_name(r), (r->server), current_logtime(msr->mp), ap_get_server_name(r), (r->server),
r, ((r->uri == NULL) ? "" : log_escape_nq(msr->mp, r->uri)), r, ((r->uri == NULL) ? "" : log_escape_nq(msr->mp, r->uri)),
level, str1); level, str1);
/* Add a newline if there is not one already (needed for msr_log_*) */
if (str2[str2len - 1] != '\n') {
str2[str2len] = '\n';
str2[str2len + 1] = '\0';
}
/* Write to the debug log. */ /* Write to the debug log. */
if ((debuglog_fd != NULL)&&(level <= filter_debug_level)) { if ((debuglog_fd != NULL)&&(level <= filter_debug_level)) {
nbytes = strlen(str2); nbytes = strlen(str2);
@ -326,27 +321,59 @@ void msr_log(modsec_rec *msr, int level, const char *text, ...) {
/** /**
* Logs one message at level 3 to the debug log and to the * Logs one message at level 3 to the debug log and to the
* Apache error log. This is intended for error callbacks. * Apache error log. This is intended for error callbacks.
*
* The 'text' will first be escaped.
*/ */
void msr_log_error(modsec_rec *msr, const char *text, ...) { void msr_log_error(modsec_rec *msr, const char *text, ...) {
const char *str = text;
va_list ap; va_list ap;
int len;
char *str;
/* Generate the string. */
va_start(ap, text); va_start(ap, text);
internal_log(msr->r, msr->txcfg, msr, 3, str, ap); str = apr_pvsprintf(msr->mp, text, ap);
va_end(ap); va_end(ap);
/* Strip line ending. */
len = strlen(str);
if (len && str[len - 1] == '\n') {
str[len - 1] = '\0';
}
if (len > 1 && str[len - 2] == '\r') {
str[len - 1] = '\0';
}
/* Log the escaped string. */
internal_log(msr->r, msr->txcfg, msr, 3, log_escape_nq(msr->mp,str), NULL);
} }
/** /**
* Logs one message at level 4 to the debug log and to the * Logs one message at level 4 to the debug log and to the
* Apache error log. This is intended for warning callbacks. * Apache error log. This is intended for warning callbacks.
*
* The 'text' will first be escaped.
*/ */
void msr_log_warn(modsec_rec *msr, const char *text, ...) { void msr_log_warn(modsec_rec *msr, const char *text, ...) {
const char *str = text;
va_list ap; va_list ap;
int len;
char *str;
/* Generate the string. */
va_start(ap, text); va_start(ap, text);
internal_log(msr->r, msr->txcfg, msr, 4, str, ap); str = apr_pvsprintf(msr->mp, text, ap);
va_end(ap); va_end(ap);
/* Strip line ending. */
len = strlen(str);
if (len && str[len - 1] == '\n') {
str[len - 1] = '\0';
}
if (len > 1 && str[len - 2] == '\r') {
str[len - 1] = '\0';
}
/* Log the escaped string. */
internal_log(msr->r, msr->txcfg, msr, 4, log_escape_nq(msr->mp,str), NULL);
} }

View File

@ -12,9 +12,9 @@ AC_DEFUN([CHECK_LIBXML2],
[dnl [dnl
AC_ARG_WITH( AC_ARG_WITH(
xml, libxml,
[AC_HELP_STRING([--with-xml=PATH],[Path to xml prefix or config script])], [AC_HELP_STRING([--with-libxml=PATH],[Path to libxml2 prefix or config script])],
[test_paths="${with_xml}"], [test_paths="${with_libxml}"],
[test_paths="/usr/local/libxml2 /usr/local/xml2 /usr/local/xml /usr/local /opt/libxml2 /opt/libxml /opt/xml2 /opt/xml /opt /usr"]) [test_paths="/usr/local/libxml2 /usr/local/xml2 /usr/local/xml /usr/local /opt/libxml2 /opt/libxml /opt/xml2 /opt/xml /opt /usr"])
AC_MSG_CHECKING([for libxml2 config script]) AC_MSG_CHECKING([for libxml2 config script])
@ -23,31 +23,31 @@ for x in ${test_paths}; do
dnl # Determine if the script was specified and use it directly dnl # Determine if the script was specified and use it directly
if test ! -d "$x" -a -e "$x"; then if test ! -d "$x" -a -e "$x"; then
LIBXML2_CONFIG="`basename $x`" LIBXML2_CONFIG="`basename $x`"
xml_path=`echo $x | sed "s/\/\?${LIBXML2_CONFIG}\$//"` libxml2_path=`echo $x | sed "s/\/\?${LIBXML2_CONFIG}\$//"`
break break
fi fi
dnl # Try known config script names/locations dnl # Try known config script names/locations
for LIBXML2_CONFIG in xml2-config xml-2-config xml-config; do for LIBXML2_CONFIG in xml2-config xml-2-config xml-config; do
if test -e "${x}/bin/${LIBXML2_CONFIG}"; then if test -e "${x}/bin/${LIBXML2_CONFIG}"; then
xml_path="${x}/bin" libxml2_path="${x}/bin"
break break
elif test -e "${x}/${LIBXML2_CONFIG}"; then elif test -e "${x}/${LIBXML2_CONFIG}"; then
xml_path="${x}" libxml2_path="${x}"
break break
else else
xml_path="" libxml2_path=""
fi fi
done done
if test -n "$xml_path"; then if test -n "$libxml2_path"; then
break break
fi fi
done done
CFLAGS=$save_CFLAGS CFLAGS=$save_CFLAGS
LDFLAGS=$save_LDFLAGS LDFLAGS=$save_LDFLAGS
if test -n "${xml_path}"; then if test -n "${libxml2_path}"; then
LIBXML2_CONFIG="${xml_path}/${LIBXML2_CONFIG}" LIBXML2_CONFIG="${libxml2_path}/${LIBXML2_CONFIG}"
AC_MSG_RESULT([${LIBXML2_CONFIG}]) AC_MSG_RESULT([${LIBXML2_CONFIG}])
LIBXML2_CFLAGS="`${LIBXML2_CONFIG} --cflags`" LIBXML2_CFLAGS="`${LIBXML2_CONFIG} --cflags`"
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(xml CFLAGS: $LIBXML2_CFLAGS); fi if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(xml CFLAGS: $LIBXML2_CFLAGS); fi
@ -64,9 +64,9 @@ AC_SUBST(LIBXML2_CFLAGS)
if test -z "${LIBXML2_LIBS}"; then if test -z "${LIBXML2_LIBS}"; then
AC_MSG_NOTICE([*** xml library not found.]) AC_MSG_NOTICE([*** xml library not found.])
ifelse([$2], , AC_MSG_ERROR([xml library is required]), $2) ifelse([$2], , AC_MSG_ERROR([libxml2 is required]), $2)
else else
AC_MSG_NOTICE([using '${LIBXML2_LIBS}' for xml Library]) AC_MSG_NOTICE([using '${LIBXML2_LIBS}' for libxml2])
ifelse([$1], , , $1) ifelse([$1], , , $1)
fi fi
]) ])

180
apache2/configure vendored
View File

@ -681,8 +681,9 @@ MSC_PKGBASE_DIR
MSC_BASE_DIR MSC_BASE_DIR
LIBOBJS LIBOBJS
EGREP EGREP
GREP ENV_CMD
PERL PERL
GREP
RANLIB RANLIB
SET_MAKE SET_MAKE
LN_S LN_S
@ -752,7 +753,7 @@ with_apxs
with_pcre with_pcre
with_apr with_apr
with_apu with_apu
with_xml with_libxml
with_lua with_lua
with_curl with_curl
' '
@ -1405,7 +1406,7 @@ Optional Packages:
--with-pcre=PATH Path to pcre prefix or config script --with-pcre=PATH Path to pcre prefix or config script
--with-apr=PATH Path to apr prefix or config script --with-apr=PATH Path to apr prefix or config script
--with-apu=PATH Path to apu prefix or config script --with-apu=PATH Path to apu prefix or config script
--with-xml=PATH Path to xml prefix or config script --with-libxml=PATH Path to libxml2 prefix or config script
--with-lua=PATH Path to lua prefix or config script --with-lua=PATH Path to lua prefix or config script
--with-curl=PATH Path to curl prefix or config script --with-curl=PATH Path to curl prefix or config script
@ -3664,55 +3665,6 @@ else
RANLIB="$ac_cv_prog_RANLIB" RANLIB="$ac_cv_prog_RANLIB"
fi fi
for ac_prog in perl perl5
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_path_PERL+set}" = set; then
$as_echo_n "(cached) " >&6
else
case $PERL in
[\\/]* | ?:[\\/]*)
ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
;;
*)
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_path_PERL="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
PERL=$ac_cv_path_PERL
if test -n "$PERL"; then
{ $as_echo "$as_me:$LINENO: result: $PERL" >&5
$as_echo "$PERL" >&6; }
else
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$PERL" && break
done
# Checks for header files.
{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 { $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; } $as_echo_n "checking for grep that handles long lines and -e... " >&6; }
if test "${ac_cv_path_GREP+set}" = set; then if test "${ac_cv_path_GREP+set}" = set; then
@ -3778,6 +3730,100 @@ $as_echo "$ac_cv_path_GREP" >&6; }
GREP="$ac_cv_path_GREP" GREP="$ac_cv_path_GREP"
for ac_prog in perl perl5
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_path_PERL+set}" = set; then
$as_echo_n "(cached) " >&6
else
case $PERL in
[\\/]* | ?:[\\/]*)
ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
;;
*)
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_path_PERL="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
PERL=$ac_cv_path_PERL
if test -n "$PERL"; then
{ $as_echo "$as_me:$LINENO: result: $PERL" >&5
$as_echo "$PERL" >&6; }
else
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$PERL" && break
done
for ac_prog in env printenv
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_path_ENV_CMD+set}" = set; then
$as_echo_n "(cached) " >&6
else
case $ENV_CMD in
[\\/]* | ?:[\\/]*)
ac_cv_path_ENV_CMD="$ENV_CMD" # Let the user override the test with a path.
;;
*)
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_path_ENV_CMD="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
ENV_CMD=$ac_cv_path_ENV_CMD
if test -n "$ENV_CMD"; then
{ $as_echo "$as_me:$LINENO: result: $ENV_CMD" >&5
$as_echo "$ENV_CMD" >&6; }
else
{ $as_echo "$as_me:$LINENO: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$ENV_CMD" && break
done
# Checks for header files.
{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 { $as_echo "$as_me:$LINENO: checking for egrep" >&5
$as_echo_n "checking for egrep... " >&6; } $as_echo_n "checking for egrep... " >&6; }
if test "${ac_cv_path_EGREP+set}" = set; then if test "${ac_cv_path_EGREP+set}" = set; then
@ -5535,7 +5581,7 @@ CURL_MIN_VERSION="7.15.1"
### Build *EXTRA_CFLAGS vars ### Build *EXTRA_CFLAGS vars
# Allow overriding EXTRA_CFLAGS # Allow overriding EXTRA_CFLAGS
if env | grep "^EXTRA_CFLAGS" > /dev/null 2>&1; then if $ENV_CMD | $GREP "^EXTRA_CFLAGS" > /dev/null 2>&1; then
if test -z "$debug_mem"; then if test -z "$debug_mem"; then
EXTRA_CFLAGS="$EXTRA_CFLAGS $strict_compile" EXTRA_CFLAGS="$EXTRA_CFLAGS $strict_compile"
fi fi
@ -5815,9 +5861,9 @@ fi
# Check whether --with-xml was given. # Check whether --with-libxml was given.
if test "${with_xml+set}" = set; then if test "${with_libxml+set}" = set; then
withval=$with_xml; test_paths="${with_xml}" withval=$with_libxml; test_paths="${with_libxml}"
else else
test_paths="/usr/local/libxml2 /usr/local/xml2 /usr/local/xml /usr/local /opt/libxml2 /opt/libxml /opt/xml2 /opt/xml /opt /usr" test_paths="/usr/local/libxml2 /usr/local/xml2 /usr/local/xml /usr/local /opt/libxml2 /opt/libxml /opt/xml2 /opt/xml /opt /usr"
fi fi
@ -5829,30 +5875,30 @@ $as_echo_n "checking for libxml2 config script... " >&6; }
for x in ${test_paths}; do for x in ${test_paths}; do
if test ! -d "$x" -a -e "$x"; then if test ! -d "$x" -a -e "$x"; then
LIBXML2_CONFIG="`basename $x`" LIBXML2_CONFIG="`basename $x`"
xml_path=`echo $x | sed "s/\/\?${LIBXML2_CONFIG}\$//"` libxml2_path=`echo $x | sed "s/\/\?${LIBXML2_CONFIG}\$//"`
break break
fi fi
for LIBXML2_CONFIG in xml2-config xml-2-config xml-config; do for LIBXML2_CONFIG in xml2-config xml-2-config xml-config; do
if test -e "${x}/bin/${LIBXML2_CONFIG}"; then if test -e "${x}/bin/${LIBXML2_CONFIG}"; then
xml_path="${x}/bin" libxml2_path="${x}/bin"
break break
elif test -e "${x}/${LIBXML2_CONFIG}"; then elif test -e "${x}/${LIBXML2_CONFIG}"; then
xml_path="${x}" libxml2_path="${x}"
break break
else else
xml_path="" libxml2_path=""
fi fi
done done
if test -n "$xml_path"; then if test -n "$libxml2_path"; then
break break
fi fi
done done
CFLAGS=$save_CFLAGS CFLAGS=$save_CFLAGS
LDFLAGS=$save_LDFLAGS LDFLAGS=$save_LDFLAGS
if test -n "${xml_path}"; then if test -n "${libxml2_path}"; then
LIBXML2_CONFIG="${xml_path}/${LIBXML2_CONFIG}" LIBXML2_CONFIG="${libxml2_path}/${LIBXML2_CONFIG}"
{ $as_echo "$as_me:$LINENO: result: ${LIBXML2_CONFIG}" >&5 { $as_echo "$as_me:$LINENO: result: ${LIBXML2_CONFIG}" >&5
$as_echo "${LIBXML2_CONFIG}" >&6; } $as_echo "${LIBXML2_CONFIG}" >&6; }
LIBXML2_CFLAGS="`${LIBXML2_CONFIG} --cflags`" LIBXML2_CFLAGS="`${LIBXML2_CONFIG} --cflags`"
@ -5874,12 +5920,12 @@ fi
if test -z "${LIBXML2_LIBS}"; then if test -z "${LIBXML2_LIBS}"; then
{ $as_echo "$as_me:$LINENO: *** xml library not found." >&5 { $as_echo "$as_me:$LINENO: *** xml library not found." >&5
$as_echo "$as_me: *** xml library not found." >&6;} $as_echo "$as_me: *** xml library not found." >&6;}
{ { $as_echo "$as_me:$LINENO: error: xml library is required" >&5 { { $as_echo "$as_me:$LINENO: error: libxml2 is required" >&5
$as_echo "$as_me: error: xml library is required" >&2;} $as_echo "$as_me: error: libxml2 is required" >&2;}
{ (exit 1); exit 1; }; } { (exit 1); exit 1; }; }
else else
{ $as_echo "$as_me:$LINENO: using '${LIBXML2_LIBS}' for xml Library" >&5 { $as_echo "$as_me:$LINENO: using '${LIBXML2_LIBS}' for libxml2" >&5
$as_echo "$as_me: using '${LIBXML2_LIBS}' for xml Library" >&6;} $as_echo "$as_me: using '${LIBXML2_LIBS}' for libxml2" >&6;}
fi fi

View File

@ -20,7 +20,9 @@ AC_PROG_INSTALL
AC_PROG_LN_S AC_PROG_LN_S
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
AC_PROG_RANLIB AC_PROG_RANLIB
AC_PROG_GREP
AC_PATH_PROGS(PERL, [perl perl5], ) AC_PATH_PROGS(PERL, [perl perl5], )
AC_PATH_PROGS(ENV_CMD, [env printenv], )
# Checks for header files. # Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
@ -286,7 +288,7 @@ sinclude(build/find_curl.m4)
### Build *EXTRA_CFLAGS vars ### Build *EXTRA_CFLAGS vars
# Allow overriding EXTRA_CFLAGS # Allow overriding EXTRA_CFLAGS
if env | grep "^EXTRA_CFLAGS" > /dev/null 2>&1; then if $ENV_CMD | $GREP "^EXTRA_CFLAGS" > /dev/null 2>&1; then
if test -z "$debug_mem"; then if test -z "$debug_mem"; then
EXTRA_CFLAGS="$EXTRA_CFLAGS $strict_compile" EXTRA_CFLAGS="$EXTRA_CFLAGS $strict_compile"
fi fi

View File

@ -22,7 +22,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#if !(defined(_AIX) || defined(WIN32) || defined(CYGWIN) || defined(NETWARE) || defined(SOLARIS2)) /* ENH: Clean this mess up */
#if !(defined(_AIX) || defined(WIN32) || defined(CYGWIN) || defined(NETWARE) || defined(SOLARIS2) || defined(__osf1__))
#define DSOLOCAL __attribute__((visibility("hidden"))) #define DSOLOCAL __attribute__((visibility("hidden")))
#else #else
#define DSOLOCAL #define DSOLOCAL

View File

@ -48,6 +48,55 @@
), ),
), ),
}, },
# Failed attribute value
{
type => "rule",
comment => "validateSchema (validate attribute value failed)",
conf => qq(
SecRuleEngine On
SecRequestBodyAccess On
SecDebugLog $ENV{DEBUG_LOG}
SecDebugLogLevel 9
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
SecRule XML "\@validateSchema $ENV{CONF_DIR}/SoapEnvelope.xsd" \\
"phase:2,deny,log,auditlog,id:12345"
),
match_log => {
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*'badval' is not a valid value of the local atomic type.*Schema validation failed/s, 1 ],
-debug => [ qr/Successfully validated payload against Schema|\n\r?\n/, 1 ],
audit => [ qr/^Message: Element.*'badval' is not a valid value of the local atomic type\.\nMessage:/m, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "text/xml",
],
normalize_raw_request_data(
q(
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.bluebank.example.com/axis/getBalance.jws"
xmlns:types="http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body soap:mustUnderstand="badval" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<q1:getInput xmlns:q1="http://DefaultNamespace">
<id xsi:type="xsd:string">12123</id>
</q1:getInput>
</soap:Body>
</soap:Envelope>
),
),
),
},
# Failed validation # Failed validation
{ {
type => "rule", type => "rule",
@ -57,6 +106,8 @@
SecRequestBodyAccess On SecRequestBodyAccess On
SecDebugLog $ENV{DEBUG_LOG} SecDebugLog $ENV{DEBUG_LOG}
SecDebugLogLevel 9 SecDebugLogLevel 9
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\ SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML" "phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345 SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
@ -67,6 +118,7 @@
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*element is not expected/s, 1 ], debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*element is not expected/s, 1 ],
-debug => [ qr/XML parser error|Failed to load/, 1 ], -debug => [ qr/XML parser error|Failed to load/, 1 ],
-error => [ qr/XML parser error|Failed to load/, 1 ], -error => [ qr/XML parser error|Failed to load/, 1 ],
audit => [ qr/^Message: Element.*This element is not expected.*\nMessage:/m, 1 ],
}, },
match_response => { match_response => {
status => qr/^403$/, status => qr/^403$/,
@ -104,6 +156,8 @@
SecRequestBodyAccess On SecRequestBodyAccess On
SecDebugLog $ENV{DEBUG_LOG} SecDebugLog $ENV{DEBUG_LOG}
SecDebugLogLevel 9 SecDebugLogLevel 9
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\ SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML" "phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345 SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
@ -114,6 +168,7 @@
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 0\).*XML parser error.*validation failed because content is not well formed/s, 1 ], debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 0\).*XML parser error.*validation failed because content is not well formed/s, 1 ],
-debug => [ qr/Failed to load|Successfully validated/, 1 ], -debug => [ qr/Failed to load|Successfully validated/, 1 ],
-error => [ qr/Failed to load|Successfully validated/, 1 ], -error => [ qr/Failed to load|Successfully validated/, 1 ],
audit => [ qr/^Message: .*Failed parsing document.*\nMessage:/m, 1 ],
}, },
match_response => { match_response => {
status => qr/^403$/, status => qr/^403$/,
@ -151,6 +206,8 @@
SecRequestBodyAccess On SecRequestBodyAccess On
SecDebugLog $ENV{DEBUG_LOG} SecDebugLog $ENV{DEBUG_LOG}
SecDebugLogLevel 9 SecDebugLogLevel 9
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\ SecRule REQUEST_HEADERS:Content-Type "^text/xml\$" \\
"phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML" "phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML"
SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345 SecRule REQBODY_PROCESSOR "!^XML\$" nolog,pass,skipAfter:12345
@ -159,6 +216,7 @@
), ),
match_log => { match_log => {
debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*Failed to parse the XML resource.*Failed to load Schema/s, 1 ], debug => [ qr/XML: Initialising parser.*XML: Parsing complete \(well_formed 1\).*Target value: "\[XML document tree\]".*Failed to parse the XML resource.*Failed to load Schema/s, 1 ],
audit => [ qr/^Message: .*Failed to parse the XML resource.*\nMessage: Rule processing failed/m, 1 ],
}, },
match_response => { match_response => {
status => qr/^200$/, status => qr/^200$/,

View File

@ -6,7 +6,7 @@
Manual</title> Manual</title>
<articleinfo> <articleinfo>
<releaseinfo>Version 2.6.0-trunk (May 15, 2009)</releaseinfo> <releaseinfo>Version 2.6.0-trunk (May 29, 2009)</releaseinfo>
<copyright> <copyright>
<year>2004-2009</year> <year>2004-2009</year>
@ -5555,7 +5555,7 @@ end</programlisting>
<para><emphasis>Description:</emphasis> Phrase Match operator. This <para><emphasis>Description:</emphasis> Phrase Match operator. This
operator uses a set based matching engine (Aho-Corasick) for faster operator uses a set based matching engine (Aho-Corasick) for faster
matches of keyword lists. It will match any one of its arguments matches of keyword lists. It will match any one of its arguments
anywhere in the target value.</para> anywhere in the target value. The match is case insensitive.</para>
<para>Example:</para> <para>Example:</para>