Fixed deny not work in response phase, Fixed debug log message

This commit is contained in:
chaizhenhua 2013-01-30 23:29:56 +08:00
parent 65d889664c
commit 1a89b6b8a6
2 changed files with 72 additions and 47 deletions

View File

@ -183,8 +183,10 @@ ngx_http_modsecurity_merge_loc_conf(ngx_conf_t *cf, void *parent,
ngx_conf_merge_ptr_value(conf->config, prev->config, NULL);
if (conf->enable && conf->config == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"ModSecurity: enabled in %V:%ui while no config file is specified ",
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"\"ModSecurityEnabled\" in %V:%ui is set to \"on\""
" while directive \"ModSecurityConfig\" is not found"
" in the same location",
conf->file, conf->line);
return NGX_CONF_ERROR;
}
@ -224,6 +226,7 @@ modsec_pcre_free(void *ptr)
static ngx_int_t
ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf)
{
server_rec *s;
/* XXX: temporary hack, nginx uses pcre as well and hijacks these two */
pcre_malloc = modsec_pcre_malloc;
@ -232,9 +235,20 @@ ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf)
modsecSetLogHook(cf->log, modsecLog);
modsecSetDropAction(ngx_http_modsecurity_drop_action);
modsecInit();
modsecStartConfig();
s = modsecInit();
if (s == NULL) {
return NGX_ERROR;
}
/* set host name */
s->server_hostname = ngx_palloc(cf->pool, ngx_cycle->hostname.len + 1);
if (s->server_hostname == NULL) {
return NGX_ERROR;
}
ngx_memcpy(s->server_hostname, ngx_cycle->hostname.data, ngx_cycle->hostname.len);
s->server_hostname[ ngx_cycle->hostname.len] = '\0';
modsecStartConfig();
return NGX_OK;
}
@ -344,8 +358,6 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
ngx_http_modsecurity_ctx_t *ctx;
ngx_int_t rc;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: handler");
cf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity);
/* Process only main request */
@ -353,6 +365,8 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: handler");
ctx = ngx_http_modsecurity_create_ctx(r);
if (ctx == NULL) {
return NGX_ERROR;
@ -360,15 +374,11 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
ngx_http_set_ctx(r, ctx, ngx_http_modsecurity);
/* processing request headers */
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: process request headers");
rc = modsecProcessRequestHeaders(ctx->req);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestHeaders %d", rc);
if (rc == DECLINED) {
if (r->method == NGX_HTTP_POST) {
/* Processing POST request body, should we process PUT? */
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: method POST");
rc = ngx_http_read_client_request_body(r, ngx_http_modsecurity_body_handler);
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
return rc;
@ -377,12 +387,11 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r)
return NGX_DONE;
}
/* other method */
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: process request body");
rc = modsecProcessRequestBody(ctx->req);
rc = modsecProcessRequestBody(ctx->req);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestBody %d", rc);
}
if (rc != DECLINED) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: status: %d, need action", rc);
/* Nginx and Apache share same response code */
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
@ -412,7 +421,7 @@ ngx_http_modsecurity_body_handler(ngx_http_request_t *r)
return;
}
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: process request body");
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: body handler");
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
@ -426,9 +435,9 @@ ngx_http_modsecurity_body_handler(ngx_http_request_t *r)
modsecSetBodyBrigade(ctx->req, ctx->brigade);
rc = modsecProcessRequestBody(ctx->req);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestBody %d", rc);
if (rc != DECLINED) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: status: %d, need action", rc);
/* Nginx and Apache share same response code */
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
@ -474,21 +483,17 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r) {
ngx_http_modsecurity_loc_conf_t *cf;
ngx_http_modsecurity_ctx_t *ctx;
const char *lang;
ngx_int_t rc;
cf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity);
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
if (r != r->main || r->internal || !cf->enable || ctx->complete) {
return ngx_http_next_header_filter(r);
}
if (r->method == NGX_HTTP_HEAD || r->header_only
|| !modsecIsResponseBodyAccessEnabled(ctx->req) ) {
/* TODO: RESPONSE HEADERS PHASE
*/
return ngx_http_next_header_filter(r);
}
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: header filter");
/* copy headers_out */
if (ngx_list_copy_to_apr_table(&r->headers_out.headers,
ctx->req->headers_out,
@ -507,6 +512,22 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r) {
*(const char **)apr_array_push(ctx->req->content_languages) = lang;
}
if (r->method == NGX_HTTP_HEAD || r->header_only) {
ctx->complete = 1;
rc = modsecProcessResponse(ctx->req);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessResponse %d", rc);
if (rc == DECLINED || rc == APR_SUCCESS) {
return ngx_http_next_header_filter(r);
}
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
}
return rc;
}
return NGX_OK;
}
@ -520,7 +541,7 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
cf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity);
ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
if (r != r->main || r->internal || !cf->enable || ctx->complete) {
return ngx_http_next_body_filter(r, in);
}
@ -532,10 +553,8 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
rc = move_chain_to_brigade(in, ctx->brigade, r->pool);
if (rc == NGX_ERROR) {
return NGX_ERROR;
} else if (rc == NGX_AGAIN) {
return NGX_AGAIN;
if (rc != NGX_OK) {
return rc;
}
/* last buf has been saved */
@ -544,6 +563,7 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
modsecSetResponseBrigade(ctx->req, ctx->brigade);
rc = modsecProcessResponse(ctx->req);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessResponse %d", rc);
if (rc == DECLINED || rc == APR_SUCCESS) {
@ -565,22 +585,17 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
rc = ngx_http_next_header_filter(r);
if (rc == NGX_ERROR || rc > NGX_OK) {
return rc;
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc);
}
rc = ngx_http_next_body_filter(r, in);
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
return rc;
}
return NGX_OK;
return ngx_http_next_body_filter(r, in);
}
if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) {
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
}
return rc; /* ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc); */
return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc);
}
@ -709,7 +724,8 @@ ngx_http_modsecurity_config(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
msg = modsecProcessConfig(mscf->config, (const char *)value[1].data, NULL);
if (msg != NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "modSecurity: modsecProcessConfig() %s", msg);
ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "ModSecurityConfig in %s:%ui: %s",
cf->conf_file->file.name.data, cf->conf_file->line, msg);
return NGX_CONF_ERROR;
}

View File

@ -215,7 +215,11 @@ apr_status_t ap_http_in_filter(ap_filter_t *f, apr_bucket_brigade *bb_out,
return APR_SUCCESS;
}
return AP_NOBODY_READ;
/* cannot read request body */
e = apr_bucket_eos_create(f->c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb_out, e);
return APR_SUCCESS;
}
apr_status_t ap_http_out_filter(ap_filter_t *f, apr_bucket_brigade *b) {
@ -560,7 +564,7 @@ int modsecProcessResponse(request_rec *r) {
if (bb == NULL) {
msr_log(msr, 1, "Process response: Failed to create brigade.");
return -1;
return APR_EGENERAL;
}
msr->r = r;
@ -583,19 +587,24 @@ int modsecProcessResponse(request_rec *r) {
e = apr_bucket_pool_create(tmp, readcnt, r->pool, r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
}
if(is_eos) {
e = apr_bucket_eos_create(r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
}
}
e = apr_bucket_eos_create(r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
} else {
return AP_NOBODY_WROTE;
/* cannot read response body process header only */
e = apr_bucket_eos_create(r->connection->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, e);
}
f = ap_add_output_filter("HTTP_OUT", msr, r, r->connection);
status = ap_pass_brigade(r->output_filters, bb);
ap_remove_output_filter(f);
if(status > 0
&& msr->intercept_actionset->intercept_status != 0) {
status = msr->intercept_actionset->intercept_status;
}
return status;
}