diff --git a/apache2/t/regression/action/00-disruptive-actions.t b/apache2/t/regression/action/00-disruptive-actions.t
index 6cae4a3f..bc2521f0 100644
--- a/apache2/t/regression/action/00-disruptive-actions.t
+++ b/apache2/t/regression/action/00-disruptive-actions.t
@@ -299,6 +299,7 @@
},
match_response => {
status => qr/^200$/,
+ content => qr/^TEST$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test2.txt",
@@ -316,6 +317,7 @@
},
match_response => {
status => qr/^200$/,
+ content => qr/^TEST$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test2.txt",
@@ -333,6 +335,7 @@
},
match_response => {
status => qr/^200$/,
+ content => qr/^TEST$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test2.txt",
@@ -350,6 +353,7 @@
},
match_response => {
status => qr/^200$/,
+ content => qr/^TEST$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test2.txt",
@@ -369,6 +373,7 @@
},
match_response => {
status => qr/^200$/,
+ content => qr/^TEST$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test2.txt",
@@ -386,6 +391,7 @@
},
match_response => {
status => qr/^200$/,
+ content => qr/^TEST$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test2.txt",
diff --git a/apache2/t/regression/config/00-audit-directives.t b/apache2/t/regression/config/00-audit-directives.t
new file mode 100644
index 00000000..e79c21f8
--- /dev/null
+++ b/apache2/t/regression/config/00-audit-directives.t
@@ -0,0 +1,188 @@
+### SecAudit* directive tests
+{
+ type => "config",
+ comment => "SecAuditEngine On",
+ conf => qq(
+ SecAuditEngine On
+ SecAuditLog $ENV{AUDIT_LOG}
+ ),
+ match_log => {
+ audit => [ qr/./, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ ),
+},
+{
+ type => "config",
+ comment => "SecAuditEngine Off",
+ conf => qq(
+ SecAuditEngine Off
+ SecAuditLog $ENV{AUDIT_LOG}
+ ),
+ match_log => {
+ -audit => [ qr/./, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ ),
+},
+{
+ type => "config",
+ comment => "SecAuditEngine RelevantOnly (pos)",
+ conf => qq(
+ SecRuleEngine On
+ SecAuditEngine RelevantOnly
+ SecAuditLog $ENV{AUDIT_LOG}
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 9
+ SecResponseBodyAccess On
+ SecDefaultAction "phase:2,log,auditlog,pass"
+ SecRule REQUEST_URI "." "phase:4,deny"
+ ),
+ match_log => {
+ audit => [ qr/./, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ ),
+},
+{
+ type => "config",
+ comment => "SecAuditEngine RelevantOnly (neg)",
+ conf => qq(
+ SecAuditEngine RelevantOnly
+ SecAuditLog $ENV{AUDIT_LOG}
+ SecResponseBodyAccess On
+ SecDefaultAction "phase:2,log,auditlog,pass"
+ ),
+ match_log => {
+ -audit => [ qr/./, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ ),
+},
+{
+ type => "config",
+ comment => "SecAuditLogRelevantStatus (pos)",
+ conf => qq(
+ SecAuditEngine RelevantOnly
+ SecAuditLog $ENV{AUDIT_LOG}
+ SecAuditLogRelevantStatus "^4"
+ ),
+ match_log => {
+ audit => [ qr/./, 1 ],
+ },
+ match_response => {
+ status => qr/^404$/,
+ },
+ request => new HTTP::Request(
+ GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/bogus",
+ ),
+},
+{
+ type => "config",
+ comment => "SecAuditLogRelevantStatus (neg)",
+ conf => qq(
+ SecAuditEngine RelevantOnly
+ SecAuditLog $ENV{AUDIT_LOG}
+ SecAuditLogRelevantStatus "^4"
+ ),
+ match_log => {
+ -audit => [ qr/./, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ ),
+},
+{
+ type => "config",
+ comment => "SecAuditLogParts (minimal)",
+ conf => qq(
+ SecAuditEngine On
+ SecAuditLog $ENV{AUDIT_LOG}
+ SecRequestBodyAccess On
+ SecResponseBodyAccess On
+ SecAuditLogParts "AZ"
+ ),
+ match_log => {
+ audit => [ qr/-A--.*-Z--/s, 1 ],
+ -audit => [ qr/-[B-Y]--/, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1r&=2",
+ ),
+},
+{
+ type => "config",
+ comment => "SecAuditLogParts (default)",
+ conf => qq(
+ SecAuditEngine On
+ SecAuditLog $ENV{AUDIT_LOG}
+ SecRequestBodyAccess On
+ SecResponseBodyAccess On
+ ),
+ match_log => {
+ audit => [ qr/-A--.*-B--.*-F--.*-H--.*-Z--/s, 1 ],
+ -audit => [ qr/-[DEGIJK]--/, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1r&=2",
+ ),
+},
+{
+ type => "config",
+ comment => "SecAuditLogParts (all)",
+ conf => qq(
+ SecRuleEngine On
+ SecAuditEngine On
+ SecAuditLog $ENV{AUDIT_LOG}
+ SecRequestBodyAccess On
+ SecResponseBodyAccess On
+ SecAuditLogParts "ABCDEFGHIJKZ"
+ SecAction "phase:4,log,auditlog,allow"
+ ),
+ match_log => {
+ audit => [ qr/-A--.*-B--.*-C--.*-F--.*-E--.*-H--.*-K--.*-Z--/s, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1r&=2",
+ ),
+},
diff --git a/apache2/t/regression/config/00-debug-directives.t b/apache2/t/regression/config/00-debug-directives.t
new file mode 100644
index 00000000..b5376879
--- /dev/null
+++ b/apache2/t/regression/config/00-debug-directives.t
@@ -0,0 +1,278 @@
+### SecDebug* directive tests
+{
+ type => "config",
+ comment => "SecDebugLog (pos)",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 9
+ ),
+ match_log => {
+ debug => [ qr/./, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLog (neg)",
+ conf => qq(
+ SecRuleEngine On
+ ),
+ match_log => {
+ -debug => [ qr/./, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLogLevel 0",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 0
+ SecRule REQUEST_URI "." "phase:1,deny"
+ ),
+ match_log => {
+ -debug => [ qr/./, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLogLevel 1",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 1
+ SecRuleScript "test.lua" "phase:1"
+ SecRule REQUEST_URI "(.)" "phase:4,deny,deprecatevar:bogus"
+ ),
+ match_log => {
+ debug => [ qr/\]\[[1]\] /, 1 ],
+ -debug => [ qr/\]\[[2-9]\] /, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1&b=2",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLogLevel 2",
+ conf => qq(
+ SecRuleEngine DetectionOnly
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 2
+ SecRuleScript "test.lua" "phase:1"
+ SecRule REQUEST_URI "(.)" "phase:4,deny,deprecatevar:bogus"
+ ),
+ match_log => {
+ debug => [ qr/\]\[2\] /, 1 ],
+ -debug => [ qr/\]\[[3-9]\] /, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1&b=2",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLogLevel 3",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 3
+ SecRuleScript "test.lua" "phase:1"
+ SecRule REQUEST_URI "(.)" "phase:4,deny,deprecatevar:bogus"
+ ),
+ match_log => {
+ debug => [ qr/\]\[3\] /, 1 ],
+ -debug => [ qr/\]\[[4-9]\] /, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1&b=2",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLogLevel 4",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 4
+ SecRuleScript "test.lua" "phase:1"
+ SecRule REQUEST_URI "(.)" "phase:4,deny,deprecatevar:bogus"
+ ),
+ match_log => {
+ debug => [ qr/\]\[4\] /, 1 ],
+ -debug => [ qr/\]\[[5-9]\] /, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1&b=2",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLogLevel 5",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 5
+ SecRuleScript "test.lua" "phase:1"
+ SecRule REQUEST_URI "(.)" "phase:4,deny,deprecatevar:bogus"
+ ),
+ match_log => {
+ debug => [ qr/\]\[5\] /, 1 ],
+ -debug => [ qr/\]\[[6-9]\] /, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1&b=2",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLogLevel 6",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 6
+ SecRuleScript "test.lua" "phase:1"
+ SecRule REQUEST_URI "(.)" "phase:4,deny,deprecatevar:bogus"
+ ),
+ match_log => {
+ debug => [ qr/\]\[6\] /, 1 ],
+ -debug => [ qr/\]\[[7-9]\] /, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1&b=2",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLogLevel 7",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 7
+ SecRuleScript "test.lua" "phase:1"
+ SecRule REQUEST_URI "(.)" "phase:4,deny,deprecatevar:bogus"
+ ),
+ match_log => {
+ debug => [ qr/\]\[7\] /, 1 ],
+ -debug => [ qr/\]\[[8-9]\] /, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1&b=2",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLogLevel 8",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 8
+ SecRuleScript "test.lua" "phase:1"
+ SecRule REQUEST_URI "(.)" "phase:4,deny,deprecatevar:bogus"
+ ),
+ match_log => {
+ debug => [ qr/\]\[8\] /, 1 ],
+ -debug => [ qr/\]\[9\] /, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1&b=2",
+ ),
+},
+{
+ type => "config",
+ comment => "SecDebugLogLevel 9",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 9
+ SecRuleScript "test.lua" "phase:1"
+ SecRule REQUEST_URI "(.)" "phase:4,deny,deprecatevar:bogus"
+ ),
+ match_log => {
+ debug => [ qr/\]\[9\] /, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1&b=2",
+ ),
+},
diff --git a/apache2/t/regression/rule/00-script.t b/apache2/t/regression/rule/00-script.t
new file mode 100644
index 00000000..c09b1450
--- /dev/null
+++ b/apache2/t/regression/rule/00-script.t
@@ -0,0 +1,25 @@
+
+# Lua
+{
+ type => "config",
+ comment => "SecRuleScript (lua)",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 1
+ SecRuleScript "test.lua" "phase:1"
+ ),
+ match_log => {
+ debug => [ qr/Test message\./, 1 ],
+ },
+ match_response => {
+ status => qr/^200$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => "application/x-www-form-urlencoded",
+ ],
+ "a=1;b=2",
+ ),
+},
diff --git a/apache2/t/regression/server_root/conf/httpd.conf b/apache2/t/regression/server_root/conf/httpd.conf
new file mode 100644
index 00000000..b3aa787f
--- /dev/null
+++ b/apache2/t/regression/server_root/conf/httpd.conf
@@ -0,0 +1,31 @@
+### Base configuration for starting Apache httpd
+
+# File locations
+PidFile /home/brectanu/projects/modsec/m2/trunk/apache2/t/regression/server_root/logs/httpd.pid
+ScoreBoardFile /home/brectanu/projects/modsec/m2/trunk/apache2/t/regression/server_root/logs/httpd.scoreboard
+
+
+ LoadModule proxy_module modules/mod_proxy.so
+ LoadModule proxy_http_module modules/mod_proxy_http.so
+
+
+ LoadModule unique_id_module modules/mod_unique_id.so
+
+
+
+ LoadFile /usr/lib/libxml2.so
+ LoadFile /usr/lib/liblua5.1.so
+ LoadModule security2_module modules/mod_security2.so
+
+
+ServerName localhost
+
+LogLevel debug
+ErrorLog /home/brectanu/projects/modsec/m2/trunk/apache2/t/regression/server_root/logs/error.log
+
+DocumentRoot /home/brectanu/projects/modsec/m2/trunk/apache2/t/regression/server_root/htdocs
+
+ Options Indexes FollowSymLinks
+ AllowOverride None
+
+
diff --git a/apache2/t/regression/server_root/conf/test.lua b/apache2/t/regression/server_root/conf/test.lua
new file mode 100644
index 00000000..1cff076d
--- /dev/null
+++ b/apache2/t/regression/server_root/conf/test.lua
@@ -0,0 +1,14 @@
+-- Test Lua Script to just print debug messages
+function main()
+ m.log(1, "Test message.");
+ m.log(2, "Test message.");
+ m.log(3, "Test message.");
+ m.log(4, "Test message.");
+ m.log(5, "Test message.");
+ m.log(6, "Test message.");
+ m.log(7, "Test message.");
+ m.log(8, "Test message.");
+ m.log(9, "Test message.");
+
+ return nil;
+end
diff --git a/apache2/t/regression/server_root/htdocs/index.html b/apache2/t/regression/server_root/htdocs/index.html
new file mode 100644
index 00000000..16c51c1e
--- /dev/null
+++ b/apache2/t/regression/server_root/htdocs/index.html
@@ -0,0 +1 @@
+INDEX
diff --git a/apache2/t/regression/server_root/htdocs/test.txt b/apache2/t/regression/server_root/htdocs/test.txt
new file mode 100644
index 00000000..2a02d41c
--- /dev/null
+++ b/apache2/t/regression/server_root/htdocs/test.txt
@@ -0,0 +1 @@
+TEST
diff --git a/apache2/t/regression/server_root/htdocs/test2.txt b/apache2/t/regression/server_root/htdocs/test2.txt
new file mode 100644
index 00000000..55d8fa4b
--- /dev/null
+++ b/apache2/t/regression/server_root/htdocs/test2.txt
@@ -0,0 +1 @@
+TEST 2
diff --git a/apache2/t/run-regression-tests.pl.in b/apache2/t/run-regression-tests.pl.in
index bbc88b7e..30582b68 100755
--- a/apache2/t/run-regression-tests.pl.in
+++ b/apache2/t/run-regression-tests.pl.in
@@ -186,6 +186,13 @@ sub runfile {
$httpd_up = httpd_start() ? 0 : 1;
}
+ # Run any prerun setup
+ if ($rc == 0 and exists $t{prerun} and defined $t{prerun}) {
+ dbg("Executing perl prerun...");
+ $rc = &{$t{prerun}};
+ dbg("Perl prerun returned: $rc");
+ }
+
if ($httpd_up) {
# Perform the request and check response
if (exists $t{request}) {
@@ -216,6 +223,17 @@ sub runfile {
}
}
}
+ else {
+ msg("Failed to start httpd.");
+ $rc = 1;
+ }
+
+ # Run any arbitrary perl tests
+ if ($rc == 0 and exists $t{test} and defined $t{test}) {
+ dbg("Executing perl test(s)...");
+ $rc = &{$t{test}};
+ dbg("Perl tests returned: $rc");
+ }
# Search for all log matches
if ($rc == 0 and exists $t{match_log} and defined $t{match_log}) {
@@ -411,11 +429,6 @@ sub httpd_start {
close $httpd_out;
waitpid($httpd_pid, 0);
- if (defined $out and $out ne "") {
- msg("Httpd start failed with error messages:\n$out");
- return -1
- }
-
my $rc = $?;
if ( WIFEXITED($rc) ) {
$rc = WEXITSTATUS($rc);
@@ -430,6 +443,11 @@ sub httpd_start {
$rc = -1;
}
+ if (defined $out and $out ne "") {
+ msg("Httpd start failed with error messages:\n$out");
+ return -1
+ }
+
# Look for startup msg
unless (defined match_log("error", qr/resuming normal operations/, 10)) {
quit(1, "Httpd server failed to start.");