mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 19:24:29 +03:00
Added Response Phase for Nginx
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
# Makefile.in generated by automake 1.11.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.11.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
|
||||
# Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
@@ -73,6 +73,12 @@ am__nobase_list = $(am__nobase_strip_setup); \
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(pkglibdir)"
|
||||
LTLIBRARIES = $(pkglib_LTLIBRARIES)
|
||||
standalone_la_DEPENDENCIES =
|
||||
@@ -166,6 +172,7 @@ CURL_VERSION = @CURL_VERSION@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
@@ -200,6 +207,7 @@ LUA_CFLAGS = @LUA_CFLAGS@
|
||||
LUA_LDADD = @LUA_LDADD@
|
||||
LUA_LDFLAGS = @LUA_LDFLAGS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
MODSEC_APXS_EXTRA_CFLAGS = @MODSEC_APXS_EXTRA_CFLAGS@
|
||||
MODSEC_EXTRA_CFLAGS = @MODSEC_EXTRA_CFLAGS@
|
||||
@@ -230,6 +238,7 @@ PCRE_CONFIG = @PCRE_CONFIG@
|
||||
PCRE_CPPFLAGS = @PCRE_CPPFLAGS@
|
||||
PCRE_LDADD = @PCRE_LDADD@
|
||||
PCRE_LDFLAGS = @PCRE_LDFLAGS@
|
||||
PCRE_LD_PATH = @PCRE_LD_PATH@
|
||||
PCRE_VERSION = @PCRE_VERSION@
|
||||
PERL = @PERL@
|
||||
PKG_CONFIG = @PKG_CONFIG@
|
||||
@@ -246,6 +255,7 @@ abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_AR = @ac_ct_AR@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
@@ -278,7 +288,6 @@ libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
lt_ECHO = @lt_ECHO@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
@@ -415,7 +424,7 @@ clean-pkglibLTLIBRARIES:
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
standalone.la: $(standalone_la_OBJECTS) $(standalone_la_DEPENDENCIES)
|
||||
standalone.la: $(standalone_la_OBJECTS) $(standalone_la_DEPENDENCIES) $(EXTRA_standalone_la_DEPENDENCIES)
|
||||
$(standalone_la_LINK) -rpath $(pkglibdir) $(standalone_la_OBJECTS) $(standalone_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
@@ -815,10 +824,15 @@ install-am: all-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
169
standalone/api.c
169
standalone/api.c
@@ -38,6 +38,7 @@
|
||||
#include "ap_config.h"
|
||||
#include "http_config.h"
|
||||
|
||||
#include "api.h"
|
||||
|
||||
extern void *modsecLogObj;
|
||||
extern void (*modsecLogHook)(void *obj, int level, char *str);
|
||||
@@ -143,17 +144,17 @@ server_rec *modsecInit() {
|
||||
server->server_scheme = "";
|
||||
server->timeout = 60 * 1000000;// 60 seconds
|
||||
server->wild_names = NULL;
|
||||
server->is_virtual = 0;
|
||||
server->is_virtual = 0;
|
||||
|
||||
ap_server_config_defines = apr_array_make(pool, 1, sizeof(char *));
|
||||
|
||||
// here we should add scoreboard handling for multiple processes and threads
|
||||
//
|
||||
//
|
||||
ap_scoreboard_image = (scoreboard *)apr_palloc(pool, sizeof(scoreboard));
|
||||
|
||||
memset(ap_scoreboard_image, 0, sizeof(scoreboard));
|
||||
memset(ap_scoreboard_image, 0, sizeof(scoreboard));
|
||||
|
||||
// ----------
|
||||
// ----------
|
||||
|
||||
security2_module.module_index = 0;
|
||||
|
||||
@@ -165,51 +166,91 @@ server_rec *modsecInit() {
|
||||
return server;
|
||||
}
|
||||
|
||||
apr_status_t ap_http_in_filter(ap_filter_t *f, apr_bucket_brigade *b,
|
||||
apr_status_t ap_http_in_filter(ap_filter_t *f, apr_bucket_brigade *bb_out,
|
||||
ap_input_mode_t mode, apr_read_type_e block,
|
||||
apr_off_t readbytes) {
|
||||
char *tmp = NULL;
|
||||
apr_bucket *e = NULL;
|
||||
unsigned int readcnt = 0;
|
||||
int is_eos = 0;
|
||||
apr_bucket_brigade *bb_in;
|
||||
apr_bucket *after;
|
||||
apr_status_t rv;
|
||||
|
||||
if(modsecReadBody == NULL)
|
||||
return AP_NOBODY_READ;
|
||||
bb_in = modsecGetBodyBrigade(f->r);
|
||||
|
||||
tmp = (char *)apr_palloc(f->r->pool, readbytes);
|
||||
modsecReadBody(f->r, tmp, readbytes, &readcnt, &is_eos);
|
||||
/* use request brigade */
|
||||
if (bb_in != NULL) {
|
||||
if (!APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb_in))) {
|
||||
e = apr_bucket_eos_create(f->c->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb_in, e);
|
||||
}
|
||||
|
||||
e = apr_bucket_pool_create(tmp, readcnt, f->r->pool, f->c->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(b, e);
|
||||
rv = apr_brigade_partition(bb_in, readbytes, &after);
|
||||
if (rv != APR_SUCCESS && rv != APR_INCOMPLETE) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (e = APR_BRIGADE_FIRST(bb_in); e != after; e = APR_BRIGADE_FIRST(bb_in)) {
|
||||
APR_BUCKET_REMOVE(e);
|
||||
APR_BRIGADE_INSERT_TAIL(bb_out, e);
|
||||
}
|
||||
|
||||
if(is_eos) {
|
||||
e = apr_bucket_eos_create(f->c->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(b, e);
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
/* call the callback */
|
||||
if(modsecReadBody != NULL) {
|
||||
|
||||
tmp = (char *)apr_palloc(f->r->pool, readbytes);
|
||||
modsecReadBody(f->r, tmp, readbytes, &readcnt, &is_eos);
|
||||
|
||||
e = apr_bucket_pool_create(tmp, readcnt, f->r->pool, f->c->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb_out, e);
|
||||
|
||||
if(is_eos) {
|
||||
e = apr_bucket_eos_create(f->c->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb_out, e);
|
||||
}
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
return AP_NOBODY_READ;
|
||||
}
|
||||
|
||||
apr_status_t ap_http_out_filter(ap_filter_t *f, apr_bucket_brigade *b) {
|
||||
modsec_rec *msr = (modsec_rec *)f->ctx;
|
||||
apr_status_t rc;
|
||||
apr_bucket_brigade *bb_out;
|
||||
|
||||
bb_out = modsecGetResponseBrigade(f->r);
|
||||
|
||||
|
||||
if (bb_out) {
|
||||
APR_BRIGADE_CONCAT(bb_out, b);
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
// is there a way to tell whether the response body was modified or not?
|
||||
//
|
||||
if((msr->txcfg->content_injection_enabled || msr->content_prepend_len != 0 || msr->content_append_len != 0)
|
||||
&& modsecWriteResponse != NULL && msr->txcfg->resbody_access) {
|
||||
char *data = NULL;
|
||||
apr_size_t length;
|
||||
&& msr->txcfg->resbody_access) {
|
||||
|
||||
rc = apr_brigade_pflatten(msr->of_brigade, &data, &length, msr->mp);
|
||||
if (modsecWriteResponse != NULL) {
|
||||
char *data = NULL;
|
||||
apr_size_t length;
|
||||
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Output filter: Failed to flatten brigade (%d): %s", rc,
|
||||
get_apr_error(msr->mp, rc));
|
||||
return -1;
|
||||
rc = apr_brigade_pflatten(msr->of_brigade, &data, &length, msr->mp);
|
||||
|
||||
if (rc != APR_SUCCESS) {
|
||||
msr_log(msr, 1, "Output filter: Failed to flatten brigade (%d): %s", rc,
|
||||
get_apr_error(msr->mp, rc));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TODO: return ?*/
|
||||
modsecWriteResponse(msr->r, data, msr->stream_output_length);
|
||||
}
|
||||
|
||||
modsecWriteResponse(msr->r, data, msr->stream_output_length);
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
@@ -416,13 +457,17 @@ static modsec_rec *retrieve_msr(request_rec *r) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int modsecProcessRequest(request_rec *r) {
|
||||
int modsecProcessRequestHeaders(request_rec *r) {
|
||||
return hookfn_post_read_request(r);
|
||||
}
|
||||
|
||||
int modsecProcessRequestBody(request_rec *r) {
|
||||
int status = DECLINED;
|
||||
modsec_rec *msr = NULL;
|
||||
|
||||
ap_filter_t *f = ap_add_input_filter("HTTP_IN", NULL, r, r->connection);
|
||||
apr_bucket_brigade* bb_out;
|
||||
|
||||
status = hookfn_post_read_request(r);
|
||||
status = hookfn_fixups(r);
|
||||
|
||||
ap_remove_input_filter(f);
|
||||
@@ -435,6 +480,16 @@ int modsecProcessRequest(request_rec *r) {
|
||||
if (msr == NULL)
|
||||
return status;
|
||||
|
||||
bb_out = modsecGetBodyBrigade(r);
|
||||
if (bb_out) {
|
||||
(void) apr_brigade_cleanup(bb_out);
|
||||
status = ap_get_brigade(r->input_filters, bb_out, AP_MODE_READBYTES, APR_BLOCK_READ, -1);
|
||||
if (status == APR_SUCCESS) {
|
||||
return DECLINED;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
if(msr->stream_input_data != NULL && modsecWriteBody != NULL)
|
||||
{
|
||||
// target is responsible for copying the data into correctly managed buffer
|
||||
@@ -469,12 +524,12 @@ void modsecSetConfigForIISRequestBody(request_rec *r)
|
||||
|
||||
int modsecIsResponseBodyAccessEnabled(request_rec *r)
|
||||
{
|
||||
modsec_rec *msr = retrieve_msr(r);
|
||||
modsec_rec *msr = retrieve_msr(r);
|
||||
|
||||
if(msr == NULL || msr->txcfg == NULL)
|
||||
return 0;
|
||||
if(msr == NULL || msr->txcfg == NULL)
|
||||
return 0;
|
||||
|
||||
return msr->txcfg->resbody_access;
|
||||
return msr->txcfg->resbody_access;
|
||||
}
|
||||
|
||||
int modsecProcessResponse(request_rec *r) {
|
||||
@@ -488,7 +543,7 @@ int modsecProcessResponse(request_rec *r) {
|
||||
unsigned int readcnt = 0;
|
||||
int is_eos = 0;
|
||||
ap_filter_t *f = NULL;
|
||||
apr_bucket_brigade *bb = NULL;
|
||||
apr_bucket_brigade *bb_in, *bb = NULL;
|
||||
|
||||
if (msr == NULL) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
|
||||
@@ -505,33 +560,39 @@ int modsecProcessResponse(request_rec *r) {
|
||||
}
|
||||
|
||||
msr->r = r;
|
||||
|
||||
bb_in = modsecGetResponseBrigade(r);
|
||||
|
||||
if(modsecReadResponse == NULL)
|
||||
if (bb_in != NULL) {
|
||||
APR_BRIGADE_CONCAT(bb, bb_in);
|
||||
if (!APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
|
||||
e = apr_bucket_eos_create(bb->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(bb, e);
|
||||
}
|
||||
} else if (modsecReadResponse != NULL) {
|
||||
while(!is_eos) {
|
||||
modsecReadResponse(r, buf, 8192, &readcnt, &is_eos);
|
||||
|
||||
if(readcnt > 0) {
|
||||
tmp = (char *)apr_palloc(r->pool, readcnt);
|
||||
memcpy(tmp, buf, readcnt);
|
||||
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);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return AP_NOBODY_WROTE;
|
||||
|
||||
f = ap_add_output_filter("HTTP_OUT", msr, r, r->connection);
|
||||
|
||||
while(!is_eos) {
|
||||
modsecReadResponse(r, buf, 8192, &readcnt, &is_eos);
|
||||
|
||||
if(readcnt > 0) {
|
||||
tmp = (char *)apr_palloc(r->pool, readcnt);
|
||||
memcpy(tmp, buf, readcnt);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
f = ap_add_output_filter("HTTP_OUT", msr, r, r->connection);
|
||||
status = ap_pass_brigade(r->output_filters, bb);
|
||||
|
||||
ap_remove_output_filter(f);
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@@ -60,12 +60,49 @@ conn_rec *modsecNewConnection();
|
||||
void modsecProcessConnection(conn_rec *c);
|
||||
|
||||
request_rec *modsecNewRequest(conn_rec *connection, directory_config *config);
|
||||
int modsecProcessRequest(request_rec *r);
|
||||
|
||||
int modsecProcessRequestBody(request_rec *r);
|
||||
int modsecProcessRequestHeaders(request_rec *r);
|
||||
|
||||
static inline int modsecProcessRequest(request_rec *r) {
|
||||
int status;
|
||||
status = modsecProcessRequestHeaders(r);
|
||||
if (status != DECLINED) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return modsecProcessRequestBody(r);
|
||||
}
|
||||
|
||||
|
||||
int modsecProcessResponse(request_rec *r);
|
||||
int modsecFinishRequest(request_rec *r);
|
||||
|
||||
void modsecSetLogHook(void *obj, void (*hook)(void *obj, int level, char *str));
|
||||
|
||||
#define NOTE_MSR_BRIGADE_REQUEST "modsecurity-brigade-request"
|
||||
#define NOTE_MSR_BRIGADE_RESPONSE "modsecurity-brigade-response"
|
||||
|
||||
static inline void
|
||||
modsecSetBodyBrigade(request_rec *r, apr_bucket_brigade *b) {
|
||||
apr_table_setn(r->notes, NOTE_MSR_BRIGADE_REQUEST, (char *)b);
|
||||
};
|
||||
|
||||
static inline apr_bucket_brigade *
|
||||
modsecGetBodyBrigade(request_rec *r) {
|
||||
return (apr_bucket_brigade *)apr_table_get(r->notes, NOTE_MSR_BRIGADE_REQUEST);
|
||||
};
|
||||
|
||||
static inline void
|
||||
modsecSetResponseBrigade(request_rec *r, apr_bucket_brigade *b) {
|
||||
apr_table_setn(r->notes, NOTE_MSR_BRIGADE_RESPONSE, (char *)b);
|
||||
};
|
||||
|
||||
static inline apr_bucket_brigade *
|
||||
modsecGetResponseBrigade(request_rec *r) {
|
||||
return (apr_bucket_brigade *)apr_table_get(r->notes, NOTE_MSR_BRIGADE_RESPONSE);
|
||||
};
|
||||
|
||||
void modsecSetReadBody(apr_status_t (*func)(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos));
|
||||
void modsecSetReadResponse(apr_status_t (*func)(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos));
|
||||
void modsecSetWriteBody(apr_status_t (*func)(request_rec *r, char *buf, unsigned int length));
|
||||
|
Reference in New Issue
Block a user