Merge branch 'nginx_refactoring' of github.com:defanator/ModSecurity into nginx_refactoring

This commit is contained in:
Andrei Belov
2014-05-14 13:25:14 +04:00
10 changed files with 874 additions and 580 deletions

View File

@@ -62,7 +62,9 @@ static apr_status_t nginx_bucket_read(apr_bucket *b, const char **str,
return APR_EGENERAL;
}
size = ngx_read_file(buf->file, data, ngx_buf_size(buf), buf->file_pos);
size = ngx_read_file(buf->file, data, ngx_buf_size(buf),
buf->file_pos);
if (size != ngx_buf_size(buf)) {
apr_bucket_free(data);
return APR_EGENERAL;
@@ -153,11 +155,45 @@ ngx_buf_t * apr_bucket_to_ngx_buf(apr_bucket *e, ngx_pool_t *pool) {
return buf;
}
ngx_int_t
move_chain_to_brigade(ngx_chain_t *chain, apr_bucket_brigade *bb, ngx_pool_t *pool, ngx_int_t last_buf) {
ngx_int_t copy_chain_to_brigade(ngx_chain_t *chain_orig,
apr_bucket_brigade *bb, ngx_pool_t *pool, ngx_int_t last_buf)
{
apr_bucket *e;
ngx_chain_t *chain = chain_orig;
while (chain) {
e = ngx_buf_to_apr_bucket(chain->buf, bb->p, bb->bucket_alloc);
if (e == NULL) {
return NGX_ERROR;
}
APR_BRIGADE_INSERT_TAIL(bb, e);
if (chain->buf->last_buf) {
e = apr_bucket_eos_create(bb->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
return NGX_OK;
}
chain = chain->next;
}
if (last_buf) {
e = apr_bucket_eos_create(bb->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
return NGX_OK;
}
return NGX_AGAIN;
}
ngx_int_t move_chain_to_brigade(ngx_chain_t *chain_orig,
apr_bucket_brigade *bb, ngx_pool_t *pool, ngx_int_t last_buf)
{
apr_bucket *e;
ngx_chain_t *cl;
ngx_chain_t *chain = chain_orig;
while (chain) {
e = ngx_buf_to_apr_bucket(chain->buf, bb->p, bb->bucket_alloc);
if (e == NULL) {
@@ -168,7 +204,6 @@ move_chain_to_brigade(ngx_chain_t *chain, apr_bucket_brigade *bb, ngx_pool_t *po
if (chain->buf->last_buf) {
e = apr_bucket_eos_create(bb->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
chain->buf->last_buf = 0;
return NGX_OK;
}
cl = chain;
@@ -181,12 +216,12 @@ move_chain_to_brigade(ngx_chain_t *chain, apr_bucket_brigade *bb, ngx_pool_t *po
APR_BRIGADE_INSERT_TAIL(bb, e);
return NGX_OK;
}
return NGX_AGAIN;
}
ngx_int_t
move_brigade_to_chain(apr_bucket_brigade *bb, ngx_chain_t **ll, ngx_pool_t *pool) {
ngx_int_t move_brigade_to_chain(apr_bucket_brigade *bb,
ngx_chain_t **ll, ngx_pool_t *pool)
{
apr_bucket *e;
ngx_buf_t *buf;
ngx_chain_t *cl;
@@ -215,8 +250,10 @@ move_brigade_to_chain(apr_bucket_brigade *bb, ngx_chain_t **ll, ngx_pool_t *pool
}
cl->buf->last_buf = 1;
cl->next = NULL;
*ll = cl;
} else {
cl->next = NULL;
cl->buf->last_buf = 1;
}
apr_brigade_cleanup(bb);
@@ -243,6 +280,7 @@ move_brigade_to_chain(apr_bucket_brigade *bb, ngx_chain_t **ll, ngx_pool_t *pool
ll = &cl->next;
}
apr_brigade_cleanup(bb);
/* no eos or error */
return NGX_ERROR;

View File

@@ -13,6 +13,12 @@ apr_bucket * apr_bucket_nginx_make(apr_bucket *e, ngx_buf_t *buf,
ngx_buf_t * apr_bucket_to_ngx_buf(apr_bucket *e, ngx_pool_t *pool);
ngx_int_t move_chain_to_brigade(ngx_chain_t *chain, apr_bucket_brigade *bb, ngx_pool_t *pool, ngx_int_t last_buf);
ngx_int_t move_brigade_to_chain(apr_bucket_brigade *bb, ngx_chain_t **chain, ngx_pool_t *pool);
ngx_int_t copy_chain_to_brigade(ngx_chain_t *chain_orig,
apr_bucket_brigade *bb, ngx_pool_t *pool, ngx_int_t last_buf);
ngx_int_t move_chain_to_brigade(ngx_chain_t *chain, apr_bucket_brigade *bb,
ngx_pool_t *pool, ngx_int_t last_buf);
ngx_int_t move_brigade_to_chain(apr_bucket_brigade *bb, ngx_chain_t **chain,
ngx_pool_t *pool);

File diff suppressed because it is too large Load Diff

View File

@@ -99,7 +99,8 @@ ngx_pool_get_ctx(ngx_pool_t *pool, ngx_uint_t index)
ngx_pool_context_node_t *node;
hash = (ngx_uint_t) pool + index;
key = ngx_murmur_hash2((u_char *)&hash, sizeof(hash)) % ngx_pool_context_hash_size;
key = ngx_murmur_hash2((u_char *)&hash,
sizeof(hash)) % ngx_pool_context_hash_size;
node = ngx_pool_context_hash[key];
@@ -126,7 +127,8 @@ ngx_pool_set_ctx(ngx_pool_t *pool, ngx_uint_t index, void *data)
ngx_pool_cleanup_t *cln;
hash = (ngx_uint_t) pool + index;
key = ngx_murmur_hash2((u_char *)&hash, sizeof(hash)) % ngx_pool_context_hash_size;
key = ngx_murmur_hash2((u_char *)&hash,
sizeof(hash)) % ngx_pool_context_hash_size;
node = ngx_pool_context_hash[key];
@@ -200,7 +202,8 @@ ngx_pool_context_init_conf(ngx_cycle_t *cycle, void *conf)
ngx_pool_context_hash_size = pcf->size;
ngx_pool_context_hash = ngx_pcalloc(cycle->pool, sizeof(ngx_pool_context_node_t *) * ngx_pool_context_hash_size);
ngx_pool_context_hash = ngx_pcalloc(cycle->pool,
sizeof(ngx_pool_context_node_t *) * ngx_pool_context_hash_size);
if (ngx_pool_context_hash == NULL) {
return NGX_CONF_ERROR;

View File

@@ -6,7 +6,9 @@
void* ngx_pool_get_ctx(ngx_pool_t * pool, ngx_uint_t index);
ngx_int_t ngx_pool_set_ctx(ngx_pool_t * pool, ngx_uint_t index,void * data);
#define ngx_http_get_module_pool_ctx(r, module) ngx_pool_get_ctx(r->pool, module.index)
#define ngx_http_set_pool_ctx(r, c, module) ngx_pool_set_ctx(r->pool, module.index, c)
#define ngx_http_get_module_pool_ctx(r, module) \
ngx_pool_get_ctx(r->pool, module.index)
#define ngx_http_set_pool_ctx(r, c, module) \
ngx_pool_set_ctx(r->pool, module.index, c)
#endif /* _NGX_POOL_CONTEXT_H_INCLUDE_ */

View File

@@ -71,7 +71,7 @@
SecResponseBodyMimeType text/plain null
SecRule REQUEST_LINE "^POST" "phase:3,pass,log,auditlog,id:500177"
SecRule ARGS "val1" "phase:3,pass,log,auditlog,id:500178"
SecRule RESPONSE_HEADERS:Last-Modified "." "phase:3,pass,log,auditlog,id:500179"
SecRule RESPONSE_HEADERS:Content-type "." "phase:3,pass,log,auditlog,id:500179"
SecRule RESPONSE_BODY "TEST" "phase:3,pass,log,auditlog,id:500180"
),
match_log => {
@@ -103,7 +103,7 @@
SecDebugLogLevel 9
SecRule REQUEST_LINE "^POST" "phase:4,pass,log,auditlog,id:500181"
SecRule ARGS "val1" "phase:4,pass,log,auditlog,id:500182"
SecRule RESPONSE_HEADERS:Last-Modified "." "phase:4,pass,log,auditlog,id:500183"
SecRule RESPONSE_HEADERS:Content-Type "." "phase:4,pass,log,auditlog,id:500183"
SecRule RESPONSE_BODY "TEST" "phase:4,pass,log,auditlog,id:500184"
),
match_log => {
@@ -132,7 +132,7 @@
SecResponseBodyMimeType text/plain null
SecRule REQUEST_LINE "^POST" "phase:5,pass,log,auditlog,id:500185"
SecRule ARGS "val1" "phase:5,pass,log,auditlog,id:500186"
SecRule RESPONSE_HEADERS:Last-Modified "." "phase:5,pass,log,auditlog,id:500187"
SecRule RESPONSE_HEADERS:Content-type "." "phase:5,pass,log,auditlog,id:500187"
SecRule RESPONSE_BODY "TEST" "phase:5,pass,log,auditlog,id:500188"
),
match_log => {

View File

@@ -19,7 +19,7 @@
status => qr/^403$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/index.html",
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
@@ -46,7 +46,7 @@
status => qr/^200$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/index.html",
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
@@ -73,7 +73,7 @@
status => qr/^403$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/index.html",
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],
@@ -100,7 +100,7 @@
status => qr/^200$/,
},
request => new HTTP::Request(
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/index.html",
POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
[
"Content-Type" => "application/x-www-form-urlencoded",
],

View File

@@ -1,8 +1,10 @@
user root;
worker_processes 1;
daemon on;
worker_rlimit_core 500M;
working_directory /tmp/;
error_log logs/error.log debug;
events {
worker_connections 1024;
}
@@ -10,13 +12,44 @@ events {
http {
ModSecurityEnabled [% enable %];
ModSecurityConfig [% config %];
server {
client_body_buffer_size 1024M;
server {
client_max_body_size 30M;
listen [% listen %];
server_name localhost;
location / {
error_page 405 = $uri;
client_body_in_single_buffer on;
client_body_in_file_only on;
proxy_buffering off;
location /no-proxy/test.txt {
echo "TEST";
}
location /no-proxy/test2.txt {
echo "TEST 2";
}
location /proxy/test.txt {
proxy_pass http://localhost:[% listen %]/more/test.txt;
}
location /proxy/test2.txt {
proxy_pass http://localhost:[% listen %]/more/test2.txt;
}
location /test.txt {
echo "TEST";
}
location /test2.txt {
echo "TEST 2";
}
location / {
}
}
}

View File

@@ -388,7 +388,7 @@
),
match_log => {
error => [ qr/Pattern match "arg1" at FULL_REQUEST.*Pattern match "arg2" at FULL_REQUEST/s, 1 ],
debug => [ qr/against FULL_REQUEST.*Target value: "GET \/test.txt\?arg1=val1\&arg2=val2 HTTP\/1.1\\n\\nTE: deflate,gzip;q=0.3\\nConnection: TE, close\\nHost: localhost:8088\\nUser-Agent: ModSecurity Regression Tests\/1.2.3\\n\\n\\x00"/s, 1],
debug => [ qr/against FULL_REQUEST.*Target value: "GET \/test.txt\?arg1=val1\&arg2=val2 HTTP\/1.1\\n\\nTE: deflate,gzip;q=0.3\\nConnection: TE, close\\nHost: localhost:[0-9]+\\nUser-Agent: ModSecurity Regression Tests\/1.2.3\\n\\n\\x00"/s, 1],
},
match_response => {
status => qr/^200$/,
@@ -411,7 +411,7 @@
),
match_log => {
error => [ qr/Pattern match "arg1" at FULL_REQUEST.*Pattern match "arg2" at FULL_REQUEST/s, 1 ],
debug => [ qr/against FULL_REQUEST.*Target value: "POST \/test.txt HTTP\/1.1\\n\\nTE: deflate,gzip;q=0.3\\nConnection: TE, close\\nHost: localhost:8088\\nUser-Agent: ModSecurity Regression Tests\/1.2.3\\nContent-Type: application\/x-www-form-urlencoded\\nContent-Length: 19\\n\\narg1=val1&arg2=val2\\x00"/s, 1 ],
debug => [ qr/against FULL_REQUEST.*Target value: "POST \/test.txt HTTP\/1.1\\n\\nTE: deflate,gzip;q=0.3\\nConnection: TE, close\\nHost: localhost:[0-9]+\\nUser-Agent: ModSecurity Regression Tests\/1.2.3\\nContent-Type: application\/x-www-form-urlencoded\\nContent-Length: 19\\n\\narg1=val1&arg2=val2\\x00"/s, 1 ],
},
match_response => {
status => qr/^200$/,

View File

@@ -204,6 +204,16 @@ sub runfile {
my $rc = 0;
my $conf_fn;
# watch for segfaults
if ($t and !$t->{match_log}) {
$t->{match_log} = {};
}
if ($t and $t->{match_log} and !$t->{match_log}{-error}) {
$t->{match_log}{-error} = [];
}
push $t->{match_log}{-error}, qr/(core dump)/;
push $t->{match_log}{-error}, 1;
# Startup nginx with optionally included conf.
if (exists $t{conf} and defined $t{conf}) {
$conf_fn = sprintf "%s/%s_%s_%06d.conf",
@@ -498,7 +508,6 @@ READ: {
#dbg("Match \"$re\" in $name \"$$rbuf\" ($n)");
if ($$rbuf =~ m/$re/m) {
$rc = $&;
# print "bonga\n";
last;
}
# TODO: Use select()/poll()
@@ -695,6 +704,7 @@ sub nginx_reset_fd {
return undef;
}
# Any extras listed in "match_log"
if ($t and exists $t->{match_log}) {
for my $k (keys %{ $t->{match_log} || {} }) {