mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 13:56:01 +03:00
configs
This commit is contained in:
parent
656f7c513c
commit
e1cd024c26
@ -11,6 +11,7 @@ MAINTAINERCLEANFILES += $(CLEANFILES) \
|
||||
aclocal.m4 \
|
||||
alp2/Makefile.in \
|
||||
apache2/Makefile.in \
|
||||
java/Makefile.in \
|
||||
build/config.guess \
|
||||
build/config.sub \
|
||||
build/depcomp \
|
||||
|
45
build/ac_prog_javac.m4
Normal file
45
build/ac_prog_javac.m4
Normal file
@ -0,0 +1,45 @@
|
||||
dnl @synopsis AC_PROG_JAVAC
|
||||
dnl
|
||||
dnl AC_PROG_JAVAC tests an existing Java compiler. It uses the
|
||||
dnl environment variable JAVAC then tests in sequence various common
|
||||
dnl Java compilers. For political reasons, it starts with the free
|
||||
dnl ones.
|
||||
dnl
|
||||
dnl If you want to force a specific compiler:
|
||||
dnl
|
||||
dnl - at the configure.in level, set JAVAC=yourcompiler before calling
|
||||
dnl AC_PROG_JAVAC
|
||||
dnl
|
||||
dnl - at the configure level, setenv JAVAC
|
||||
dnl
|
||||
dnl You can use the JAVAC variable in your Makefile.in, with @JAVAC@.
|
||||
dnl
|
||||
dnl *Warning*: its success or failure can depend on a proper setting of
|
||||
dnl the CLASSPATH env. variable.
|
||||
dnl
|
||||
dnl TODO: allow to exclude compilers (rationale: most Java programs
|
||||
dnl cannot compile with some compilers like guavac).
|
||||
dnl
|
||||
dnl Note: This is part of the set of autoconf M4 macros for Java
|
||||
dnl programs. It is VERY IMPORTANT that you download the whole set,
|
||||
dnl some macros depend on other. Unfortunately, the autoconf archive
|
||||
dnl does not support the concept of set of macros, so I had to break it
|
||||
dnl for submission. The general documentation, as well as the sample
|
||||
dnl configure.in, is included in the AC_PROG_JAVA macro.
|
||||
dnl
|
||||
dnl @category Java
|
||||
dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr>
|
||||
dnl @version 2000-07-19
|
||||
dnl @license GPLWithACException
|
||||
|
||||
AC_DEFUN([AC_PROG_JAVAC],[
|
||||
AC_REQUIRE([AC_EXEEXT])dnl
|
||||
if test "x$JAVAPREFIX" = x; then
|
||||
test "x$JAVAC" = x && AC_CHECK_PROGS(JAVAC, "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT javac$EXEEXT)
|
||||
else
|
||||
test "x$JAVAC" = x && AC_CHECK_PROGS(JAVAC, "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT javac$EXEEXT, $JAVAPREFIX)
|
||||
fi
|
||||
test "x$JAVAC" = x && AC_MSG_WARN([no acceptable Java compiler found in \$PATH])
|
||||
AC_PROG_JAVAC_WORKS
|
||||
AC_PROVIDE([$0])dnl
|
||||
])
|
36
build/ac_prog_javac_works.m4
Normal file
36
build/ac_prog_javac_works.m4
Normal file
@ -0,0 +1,36 @@
|
||||
dnl @synopsis AC_PROG_JAVAC_WORKS
|
||||
dnl
|
||||
dnl Internal use ONLY.
|
||||
dnl
|
||||
dnl Note: This is part of the set of autoconf M4 macros for Java
|
||||
dnl programs. It is VERY IMPORTANT that you download the whole set,
|
||||
dnl some macros depend on other. Unfortunately, the autoconf archive
|
||||
dnl does not support the concept of set of macros, so I had to break it
|
||||
dnl for submission. The general documentation, as well as the sample
|
||||
dnl configure.in, is included in the AC_PROG_JAVA macro.
|
||||
dnl
|
||||
dnl @category Java
|
||||
dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr>
|
||||
dnl @version 2000-07-19
|
||||
dnl @license GPLWithACException
|
||||
|
||||
AC_DEFUN([AC_PROG_JAVAC_WORKS],[
|
||||
AC_CACHE_CHECK([if $JAVAC works], ac_cv_prog_javac_works, [
|
||||
JAVA_TEST=Test.java
|
||||
CLASS_TEST=Test.class
|
||||
cat << \EOF > $JAVA_TEST
|
||||
/* [#]line __oline__ "configure" */
|
||||
public class Test {
|
||||
}
|
||||
EOF
|
||||
if AC_TRY_COMMAND($JAVAC $JAVACFLAGS $JAVA_TEST) >/dev/null 2>&1; then
|
||||
ac_cv_prog_javac_works=yes
|
||||
else
|
||||
AC_MSG_ERROR([The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)])
|
||||
echo "configure: failed program was:" >&AC_FD_CC
|
||||
cat $JAVA_TEST >&AC_FD_CC
|
||||
fi
|
||||
rm -f $JAVA_TEST $CLASS_TEST
|
||||
])
|
||||
AC_PROVIDE([$0])dnl
|
||||
])
|
129
build/ax_jni_include_dir.m4
Normal file
129
build/ax_jni_include_dir.m4
Normal file
@ -0,0 +1,129 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_jni_include_dir.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_JNI_INCLUDE_DIR
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# AX_JNI_INCLUDE_DIR finds include directories needed for compiling
|
||||
# programs using the JNI interface.
|
||||
#
|
||||
# JNI include directories are usually in the java distribution This is
|
||||
# deduced from the value of JAVAC. When this macro completes, a list of
|
||||
# directories is left in the variable JNI_INCLUDE_DIRS.
|
||||
#
|
||||
# Example usage follows:
|
||||
#
|
||||
# AX_JNI_INCLUDE_DIR
|
||||
#
|
||||
# for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS
|
||||
# do
|
||||
# CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR"
|
||||
# done
|
||||
#
|
||||
# If you want to force a specific compiler:
|
||||
#
|
||||
# - at the configure.in level, set JAVAC=yourcompiler before calling
|
||||
# AX_JNI_INCLUDE_DIR
|
||||
#
|
||||
# - at the configure level, setenv JAVAC
|
||||
#
|
||||
# Note: This macro can work with the autoconf M4 macros for Java programs.
|
||||
# This particular macro is not part of the original set of macros.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Don Anderson <dda@sleepycat.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
|
||||
# TSK: This has been modifed to not error out if JNI things cannot be resolved
|
||||
# and to support scenarios whereby JAVAC is set to a location, but it is not
|
||||
# on the path.
|
||||
|
||||
#serial 7
|
||||
|
||||
AU_ALIAS([AC_JNI_INCLUDE_DIR], [AX_JNI_INCLUDE_DIR])
|
||||
AC_DEFUN([AX_JNI_INCLUDE_DIR],[
|
||||
|
||||
JNI_INCLUDE_DIRS=""
|
||||
|
||||
test "x$JAVAC" = x && AC_MSG_ERROR(['\$JAVAC' undefined])
|
||||
AC_PATH_PROG([_ACJNI_JAVAC], [$JAVAC], [no])
|
||||
|
||||
if test "x$_ACJNI_JAVAC" = xno; then
|
||||
AS_ECHO(["$JAVAC could not be found in path -- cannot resolve to JNI headers"])
|
||||
else
|
||||
_ACJNI_FOLLOW_SYMLINKS("$_ACJNI_JAVAC")
|
||||
_JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'`
|
||||
case "$host_os" in
|
||||
darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'`
|
||||
_JINC="$_JTOPDIR/Headers";;
|
||||
*) _JINC="$_JTOPDIR/include";;
|
||||
esac
|
||||
_AS_ECHO_LOG([_JTOPDIR=$_JTOPDIR])
|
||||
_AS_ECHO_LOG([_JINC=$_JINC])
|
||||
|
||||
# On Mac OS X 10.6.4, jni.h is a symlink:
|
||||
# /System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers/jni.h
|
||||
# -> ../../CurrentJDK/Headers/jni.h.
|
||||
if test -f "$_JINC/jni.h" || test -L "$_JINC/jni.h"; then
|
||||
JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JINC"
|
||||
else
|
||||
_JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'`
|
||||
if test -f "$_JTOPDIR/include/jni.h"; then
|
||||
JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include"
|
||||
else
|
||||
AS_ECHO(["cannot find java include files"])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$JNI_INCLUDE_DIRS" != x; then
|
||||
# get the likely subdirectories for system specific java includes
|
||||
case "$host_os" in
|
||||
bsdi*) _JNI_INC_SUBDIRS="bsdos";;
|
||||
linux*) _JNI_INC_SUBDIRS="linux genunix";;
|
||||
osf*) _JNI_INC_SUBDIRS="alpha";;
|
||||
solaris*) _JNI_INC_SUBDIRS="solaris";;
|
||||
mingw*) _JNI_INC_SUBDIRS="win32";;
|
||||
cygwin*) _JNI_INC_SUBDIRS="win32";;
|
||||
*) _JNI_INC_SUBDIRS="genunix";;
|
||||
esac
|
||||
|
||||
# add any subdirectories that are present
|
||||
for JINCSUBDIR in $_JNI_INC_SUBDIRS
|
||||
do
|
||||
if test -d "$_JTOPDIR/include/$JINCSUBDIR"; then
|
||||
JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$JINCSUBDIR"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
# _ACJNI_FOLLOW_SYMLINKS <path>
|
||||
# Follows symbolic links on <path>,
|
||||
# finally setting variable _ACJNI_FOLLOWED
|
||||
# ----------------------------------------
|
||||
AC_DEFUN([_ACJNI_FOLLOW_SYMLINKS],[
|
||||
# find the include directory relative to the javac executable
|
||||
_cur="$1"
|
||||
while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do
|
||||
AC_MSG_CHECKING([symlink for $_cur])
|
||||
_slink=`ls -ld "$_cur" | sed 's/.* -> //'`
|
||||
case "$_slink" in
|
||||
/*) _cur="$_slink";;
|
||||
# 'X' avoids triggering unwanted echo options.
|
||||
*) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[[^/]]*$::'`"$_slink";;
|
||||
esac
|
||||
AC_MSG_RESULT([$_cur])
|
||||
done
|
||||
_ACJNI_FOLLOWED="$_cur"
|
||||
])# _ACJNI
|
48
configure.ac
48
configure.ac
@ -17,6 +17,7 @@ AC_PREFIX_DEFAULT([/usr/local/modsecurity])
|
||||
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
|
||||
|
||||
LT_PREREQ([2.2])
|
||||
LT_INIT([dlopen])
|
||||
|
||||
@ -28,12 +29,16 @@ AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_GREP
|
||||
AC_PROG_CXX
|
||||
AC_PATH_PROGS(PERL, [perl perl5], )
|
||||
AC_PATH_PROGS(ENV_CMD, [env printenv], )
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h unistd.h sys/types.h sys/stat.h sys/utsname.h])
|
||||
AC_CHECK_HEADER([jni.h])
|
||||
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
@ -190,6 +195,46 @@ if test "$build_standalone_module" -eq 1; then
|
||||
fi
|
||||
|
||||
|
||||
# Java Module
|
||||
AC_ARG_ENABLE(java-module,
|
||||
AS_HELP_STRING([--enable-java-module],
|
||||
[Enable building java module.]),
|
||||
[
|
||||
if test "$enableval" != "no"; then
|
||||
build_java_module=1
|
||||
|
||||
m4_include([build/ax_jni_include_dir.m4])
|
||||
m4_include([build/ac_prog_javac_works.m4])
|
||||
m4_include([build/ac_prog_javac.m4])
|
||||
|
||||
# Test for java/jni so that we can compile the java bindings
|
||||
AC_PROG_JAVAC
|
||||
if test "x$JAVAC" != x; then
|
||||
AX_JNI_INCLUDE_DIR
|
||||
for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS
|
||||
do
|
||||
JNI_CPPFLAGS="$JNI_CPPFLAGS -I$JNI_INCLUDE_DIR"
|
||||
done
|
||||
# Export the paths so that the makefile gets them
|
||||
AC_SUBST(JNI_CPPFLAGS, $JNI_CPPFLAGS)
|
||||
|
||||
fi
|
||||
AM_CONDITIONAL([X_JNI],[test "x$JNI_CPPFLAGS" != x])
|
||||
|
||||
AC_SUBST(STANDALONE_CPPFLAGS, "-I../standalone")
|
||||
else
|
||||
build_java_module=0
|
||||
fi
|
||||
],
|
||||
[
|
||||
build_java_module=0
|
||||
])
|
||||
AM_CONDITIONAL([BUILD_JAVA_MODULE], [test "$build_java_module" -eq 1])
|
||||
if test "$build_java_module" -eq 1; then
|
||||
TOPLEVEL_SUBDIRS="$TOPLEVEL_SUBDIRS java"
|
||||
fi
|
||||
|
||||
|
||||
# Extensions
|
||||
AC_ARG_ENABLE(extentions,
|
||||
AS_HELP_STRING([--enable-extentions],
|
||||
@ -753,6 +798,9 @@ if test "$build_standalone_module" -ne 0; then
|
||||
AC_CONFIG_FILES([standalone/Makefile])
|
||||
AC_CONFIG_FILES([nginx/modsecurity/config])
|
||||
fi
|
||||
if test "$build_java_module" -ne 0; then
|
||||
AC_CONFIG_FILES([java/Makefile])
|
||||
fi
|
||||
if test "$build_extentions" -ne 0; then
|
||||
AC_CONFIG_FILES([ext/Makefile])
|
||||
fi
|
||||
|
90
java/Makefile.am
Normal file
90
java/Makefile.am
Normal file
@ -0,0 +1,90 @@
|
||||
pkglibdir = $(prefix)/lib
|
||||
pkglib_LTLIBRARIES = libModSecurityJNI.la
|
||||
|
||||
libModSecurityJNI_la_SOURCES = ../apache2/mod_security2.c \
|
||||
../apache2/apache2_config.c ../apache2/apache2_io.c ../apache2/apache2_util.c \
|
||||
../apache2/re.c ../apache2/re_operators.c ../apache2/re_actions.c ../apache2/re_tfns.c \
|
||||
../apache2/re_variables.c ../apache2/msc_logging.c ../apache2/msc_xml.c \
|
||||
../apache2/msc_multipart.c ../apache2/modsecurity.c ../apache2/msc_parsers.c \
|
||||
../apache2/msc_util.c ../apache2/msc_pcre.c ../apache2/persist_dbm.c ../apache2/msc_reqbody.c \
|
||||
../apache2/msc_geo.c ../apache2/msc_gsb.c ../apache2/msc_unicode.c \
|
||||
../apache2/acmp.c ../apache2/msc_lua.c ../apache2/msc_release.c \
|
||||
../apache2/msc_crypt.c ../apache2/msc_tree.c ../apache2/libinjection/libinjection_sqli.c \
|
||||
../standalone/api.c ../standalone/buckets.c \
|
||||
../standalone/config.c ../standalone/filters.c \
|
||||
../standalone/hooks.c ../standalone/regex.c ../standalone/server.c \
|
||||
org_modsecurity_ModSecurity.c
|
||||
|
||||
libModSecurityJNI_la_CFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \
|
||||
@PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @LUA_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @CURL_CFLAGS@
|
||||
#libModSecurityJNI_la_CXXFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \
|
||||
# @PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @LUA_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @CURL_CFLAGS@
|
||||
libModSecurityJNI_la_CPPFLAGS = @APR_CPPFLAGS@ @PCRE_CPPFLAGS@ @LIBXML2_CPPFLAGS@ @JNI_CPPFLAGS@
|
||||
libModSecurityJNI_la_LIBADD = @APR_LDADD@ @APU_LDADD@ @PCRE_LDADD@ @LIBXML2_LDADD@ @LUA_LDADD@
|
||||
|
||||
if AIX
|
||||
libModSecurityJNI_la_LDFLAGS = -module -avoid-version \
|
||||
@APR_LDFLAGS@ @APU_LDFLAGS@ @APXS_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@
|
||||
endif
|
||||
|
||||
if HPUX
|
||||
libModSecurityJNI_la_LDFLAGS = -module -avoid-version \
|
||||
@APR_LDFLAGS@ @APU_LDFLAGS@ @APXS_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@
|
||||
endif
|
||||
|
||||
if MACOSX
|
||||
libModSecurityJNI_la_LDFLAGS = -module -avoid-version \
|
||||
@APR_LDFLAGS@ @APU_LDFLAGS@ @APXS_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@
|
||||
endif
|
||||
|
||||
if SOLARIS
|
||||
libModSecurityJNI_la_LDFLAGS = -module -avoid-version \
|
||||
@APR_LDFLAGS@ @APU_LDFLAGS@ @APXS_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@
|
||||
endif
|
||||
|
||||
if LINUX
|
||||
libModSecurityJNI_la_LDFLAGS = -no-undefined -module -avoid-version -R @PCRE_LD_PATH@ \
|
||||
@APR_LDFLAGS@ @APU_LDFLAGS@ @APXS_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@
|
||||
endif
|
||||
|
||||
if FREEBSD
|
||||
libModSecurityJNI_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@APR_LDFLAGS@ @APU_LDFLAGS@ @APXS_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@
|
||||
endif
|
||||
|
||||
if OPENBSD
|
||||
libModSecurityJNI_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@APR_LDFLAGS@ @APU_LDFLAGS@ @APXS_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@
|
||||
endif
|
||||
|
||||
if NETBSD
|
||||
libModSecurityJNI_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@APR_LDFLAGS@ @APU_LDFLAGS@ @APXS_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@
|
||||
endif
|
||||
|
||||
|
||||
if LINUX
|
||||
install-exec-hook: $(pkglib_LTLIBRARIES)
|
||||
@echo "Removing unused static libraries..."; \
|
||||
for m in $(pkglib_LTLIBRARIES); do \
|
||||
base=`echo $$m | sed 's/\..*//'`; \
|
||||
rm -f $(DESTDIR)$(pkglibdir)/$$base.*a; \
|
||||
install -D -m444 $(DESTDIR)$(pkglibdir)/$$base.so $(DESTDIR)$(APXS_MODULES)/$$base.so; \
|
||||
done
|
||||
else
|
||||
install-exec-hook: $(pkglib_LTLIBRARIES)
|
||||
@echo "Removing unused static libraries..."; \
|
||||
for m in $(pkglib_LTLIBRARIES); do \
|
||||
base=`echo $$m | sed 's/\..*//'`; \
|
||||
rm -f $(DESTDIR)$(pkglibdir)/$$base.*a; \
|
||||
cp -p $(DESTDIR)$(pkglibdir)/$$base.so $(DESTDIR)$(APXS_MODULES); \
|
||||
done
|
||||
endif
|
@ -164,7 +164,7 @@
|
||||
<ClCompile Include="..\standalone\hooks.c" />
|
||||
<ClCompile Include="..\standalone\regex.c" />
|
||||
<ClCompile Include="..\standalone\server.c" />
|
||||
<ClCompile Include="org_modsecurity_ModSecurity.cpp" />
|
||||
<ClCompile Include="org_modsecurity_ModSecurity.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\apache2\acmp.h" />
|
||||
|
@ -117,7 +117,7 @@
|
||||
<ClCompile Include="..\standalone\server.c">
|
||||
<Filter>Standalone Sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="org_modsecurity_ModSecurity.cpp" />
|
||||
<ClCompile Include="org_modsecurity_ModSecurity.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\apache2\acmp.h">
|
||||
|
BIN
java/ModSecurityLoader/dist/ModSecurityLoader.jar
vendored
BIN
java/ModSecurityLoader/dist/ModSecurityLoader.jar
vendored
Binary file not shown.
32
java/ModSecurityLoader/dist/README.TXT
vendored
Normal file
32
java/ModSecurityLoader/dist/README.TXT
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
========================
|
||||
BUILD OUTPUT DESCRIPTION
|
||||
========================
|
||||
|
||||
When you build an Java application project that has a main class, the IDE
|
||||
automatically copies all of the JAR
|
||||
files on the projects classpath to your projects dist/lib folder. The IDE
|
||||
also adds each of the JAR files to the Class-Path element in the application
|
||||
JAR files manifest file (MANIFEST.MF).
|
||||
|
||||
To run the project from the command line, go to the dist folder and
|
||||
type the following:
|
||||
|
||||
java -jar "ModSecurityLoader.jar"
|
||||
|
||||
To distribute this project, zip up the dist folder (including the lib folder)
|
||||
and distribute the ZIP file.
|
||||
|
||||
Notes:
|
||||
|
||||
* If two JAR files on the project classpath have the same name, only the first
|
||||
JAR file is copied to the lib folder.
|
||||
* Only JAR files are copied to the lib folder.
|
||||
If the classpath contains other types of files or folders, these files (folders)
|
||||
are not copied.
|
||||
* If a library on the projects classpath also has a Class-Path element
|
||||
specified in the manifest,the content of the Class-Path element has to be on
|
||||
the projects runtime path.
|
||||
* To set a main class in a standard Java project, right-click the project node
|
||||
in the Projects window and choose Properties. Then click Run and enter the
|
||||
class name in the Main Class field. Alternatively, you can manually type the
|
||||
class name in the manifest Main-Class element.
|
@ -4,30 +4,37 @@ import java.io.File;
|
||||
|
||||
public class ModSecurityLoader {
|
||||
|
||||
private static final String MODSECURITYLIBSDIR_PATH = "c:\\work\\mod_security\\java\\libs\\"; //directory with ModSecurity native libraries
|
||||
//private static final String MODSECURITYLIBSDIR_PATH = "c:\\work\\mod_security\\java\\libs\\"; //directory with ModSecurity native libraries
|
||||
|
||||
static {
|
||||
File modSecDir = new File(MODSECURITYLIBSDIR_PATH);
|
||||
|
||||
File[] flibs = modSecDir.listFiles();
|
||||
|
||||
loadLib(flibs, "zlib1");
|
||||
loadLib(flibs, "libxml2");
|
||||
loadLib(flibs, "pcre");
|
||||
loadLib(flibs, "libapr-1");
|
||||
loadLib(flibs, "libapriconv-1");
|
||||
loadLib(flibs, "libaprutil-1");
|
||||
loadLib(flibs, "ModSecurityJNI");
|
||||
System.out.println("ModSecurity loader static block executed.");
|
||||
// File modSecDir = new File(MODSECURITYLIBSDIR_PATH);
|
||||
// File[] flibs = modSecDir.listFiles();
|
||||
// loadLib(flibs, "zlib1");
|
||||
// loadLib(flibs, "libxml2");
|
||||
// loadLib(flibs, "pcre");
|
||||
// loadLib(flibs, "libapr-1");
|
||||
// loadLib(flibs, "libapriconv-1");
|
||||
// loadLib(flibs, "libaprutil-1");
|
||||
// loadLib(flibs, "ModSecurityJNI");
|
||||
|
||||
//alternative load, this requires native libraries to be in java.library.path, you can set it
|
||||
//by specifying server VM start-up option: -Djava.library.path=path/to/libs/
|
||||
// System.loadLibrary("zlib1");
|
||||
// System.loadLibrary("libxml2");
|
||||
// System.loadLibrary("pcre");
|
||||
// System.loadLibrary("libapr-1");
|
||||
// System.loadLibrary("libapriconv-1");
|
||||
// System.loadLibrary("libaprutil-1");
|
||||
// System.loadLibrary("ModSecurityJNI");
|
||||
try {
|
||||
System.loadLibrary("zlib1"); //needed for libxml2 in Windows
|
||||
} catch(UnsatisfiedLinkError ex) {
|
||||
}
|
||||
System.loadLibrary("libxml2");
|
||||
System.loadLibrary("pcre");
|
||||
System.loadLibrary("libapr-1");
|
||||
try {
|
||||
System.loadLibrary("libapriconv-1");
|
||||
} catch(UnsatisfiedLinkError ex) { //needed for libaprutil-1 in Windows
|
||||
}
|
||||
System.loadLibrary("libaprutil-1");
|
||||
System.loadLibrary("ModSecurityJNI");
|
||||
|
||||
System.out.println("ModSecurity native libraries loaded.");
|
||||
}
|
||||
|
||||
private static void loadLib(File[] files, String lib) {
|
||||
|
@ -7,10 +7,7 @@ import java.net.UnknownHostException;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Mihai Pitu
|
||||
*/
|
||||
|
||||
public final class ModSecurity {
|
||||
//From build/classes: >"c:\Program Files\Java\jdk1.7.0_05\bin\javah.exe" -classpath c:\work\apache-tomcat-7.0.39\lib\servlet-api.jar;. org.modsecurity.ModSecurity
|
||||
|
||||
@ -23,13 +20,13 @@ public final class ModSecurity {
|
||||
|
||||
static {
|
||||
//ModSecurityLoader calls System.load() for every native library needed by ModSecurity.
|
||||
try {
|
||||
Class.forName("org.modsecurity.loader.ModSecurityLoader");
|
||||
System.out.println("ModSecurity libraries loaded.");
|
||||
} catch (ClassNotFoundException ex) {
|
||||
java.util.logging.Logger.getLogger(ModSecurity.class.getName()).log(java.util.logging.Level.SEVERE,
|
||||
"ModSecurityLoader was not found, please make sure that you have \"ModSecurityLoader.jar\" in your server lib folder.", ex);
|
||||
}
|
||||
// try {
|
||||
// Class.forName("org.modsecurity.loader.ModSecurityLoader");
|
||||
// System.out.println("ModSecurity libraries loaded.");
|
||||
// } catch (ClassNotFoundException ex) {
|
||||
// java.util.logging.Logger.getLogger(ModSecurity.class.getName()).log(java.util.logging.Level.SEVERE,
|
||||
// "ModSecurityLoader was not found, please make sure that you have \"ModSecurityLoader.jar\" in your server lib folder.", ex);
|
||||
// }
|
||||
|
||||
//If the ModSecurityLoader is not used, native libraries can be loaded here, however this is bad practice since this will raise UnsatisfiedLinkError if
|
||||
//ModSecurity is used in multiple webapps. This will also will raise problems when the web-app is redeployed and the server is running.
|
||||
@ -40,6 +37,19 @@ public final class ModSecurity {
|
||||
// System.load("c:\\work\\mod_security\\java\\libs\\libapriconv-1.dll");
|
||||
// System.load("c:\\work\\mod_security\\java\\libs\\libaprutil-1.dll");
|
||||
// System.load("c:\\work\\mod_security\\java\\Debug\\ModSecurityJNI.dll");
|
||||
try {
|
||||
System.loadLibrary("zlib1"); //needed for libxml2 in Windows
|
||||
} catch(UnsatisfiedLinkError ex) {
|
||||
}
|
||||
System.loadLibrary("libxml2");
|
||||
System.loadLibrary("pcre");
|
||||
System.loadLibrary("libapr-1");
|
||||
try {
|
||||
System.loadLibrary("libapriconv-1");
|
||||
} catch(UnsatisfiedLinkError ex) { //needed for libaprutil-1 in Windows
|
||||
}
|
||||
System.loadLibrary("libaprutil-1");
|
||||
System.loadLibrary("ModSecurityJNI");
|
||||
}
|
||||
|
||||
public ModSecurity(FilterConfig fc, String confFile) throws ServletException {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package org.modsecurity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
|
@ -491,7 +491,7 @@ public class MsHttpServletRequest extends HttpServletRequestWrapper {
|
||||
*/
|
||||
@Override
|
||||
public Enumeration getParameterNames() {
|
||||
Hashtable parameterNames = new Hashtable();
|
||||
Hashtable<Object, Object> parameterNames = new Hashtable<Object, Object>();
|
||||
for (int i = 0, n = parameters.size(); i < n; i++) {
|
||||
Parameter p = (Parameter) parameters.get(i);
|
||||
parameterNames.put(p.name, p.value);
|
||||
|
@ -25,8 +25,8 @@ public class MsHttpServletResponse extends HttpServletResponseWrapper {
|
||||
private static final int INTERCEPT_OBSERVE_ONLY = 2;
|
||||
public static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1";
|
||||
private int interceptMode = INTERCEPT_ON;
|
||||
private ArrayList headers = new ArrayList();
|
||||
private ArrayList cookies = new ArrayList();
|
||||
private ArrayList<Object> headers = new ArrayList<Object>();
|
||||
private ArrayList<Object> cookies = new ArrayList<Object>();
|
||||
private int status = -1;
|
||||
private boolean committed = false;
|
||||
private boolean suspended = false;
|
||||
@ -593,11 +593,11 @@ final class FastHttpDateFormat {
|
||||
/**
|
||||
* Formatter cache.
|
||||
*/
|
||||
protected static final HashMap formatCache = new HashMap();
|
||||
protected static final HashMap<Object, Object> formatCache = new HashMap<Object, Object>();
|
||||
/**
|
||||
* Parser cache.
|
||||
*/
|
||||
protected static final HashMap parseCache = new HashMap();
|
||||
protected static final HashMap<Object, Object> parseCache = new HashMap<Object, Object>();
|
||||
|
||||
// --------------------------------------------------------- Public Methods
|
||||
/**
|
||||
@ -705,7 +705,7 @@ final class FastHttpDateFormat {
|
||||
/**
|
||||
* Update cache.
|
||||
*/
|
||||
private static void updateCache(HashMap cache, Object key,
|
||||
private static void updateCache(HashMap<Object, Object> cache, Object key,
|
||||
Object value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
|
@ -39,17 +39,16 @@
|
||||
</p>
|
||||
|
||||
<br />
|
||||
<h3>Installation</h3>
|
||||
<h2>Installation</h2>
|
||||
<p>
|
||||
First you need to choose whether to download and compile ModSecurity from the project's version control web-site:
|
||||
<a href="https://github.com/SpiderLabs/ModSecurity">github.com/SpiderLabs/ModSecurity</a> or using pre-compiled binaries from
|
||||
<a href="https://www.modsecurity.org/">modsecurity.org</a>. We will not discuss how to compile
|
||||
the dependent native libraries needed since these steps are described in the README files from ModSecurity's repository.
|
||||
<a href="https://www.modsecurity.org/">modsecurity.org</a>.
|
||||
The native libraries (.so, .dll, etc.) needed for <b>ModSecurity for Java</b> are:
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
zlib1
|
||||
zlib1 (Windows only)
|
||||
</li>
|
||||
<li>
|
||||
libxml2
|
||||
@ -61,25 +60,53 @@
|
||||
libapr-1
|
||||
</li>
|
||||
<li>
|
||||
libapriconv-1
|
||||
libapriconv-1 (Windows only)
|
||||
</li>
|
||||
<li>
|
||||
libaprutil-1
|
||||
</li>
|
||||
<li>
|
||||
ModSecurityJNI
|
||||
ModSecurityJNI (JNI wrapper for mod_security code)
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
These native libraries are loaded by the <span class="code">ModSecurityLoader.jar</span>, which should be placed in your Java server library loader
|
||||
(for example, in Tomcat 7: <span class="code">$CATALINA_HOME/lib</span>). You can build or modify the load directory of <span class="code">ModSecurityLoader</span> from
|
||||
<span class="code">/mod_security/java/ModSecurityLoader/src/</span>. The libraries have to be copied in a directory (for example, <span class="code">c:\work\mod_security\java\libs\</span>),
|
||||
which should be accessible to <span class="code">ModSecurityLoader.jar</span>.
|
||||
These native libraries are used by the <a class="code" href="../src/java/org/modsecurity/ModSecurityFilter.java">ModSecurityFilter</a>.
|
||||
</p>
|
||||
|
||||
<br />
|
||||
<h4>Java Web Applications with ModSecurity Filter</h4>
|
||||
<h3>Compile ModSecurity native library</h3>
|
||||
<p>
|
||||
Install required packages for compilation. For example, on Debian/Ubuntu like systems (Windows users have a Visual Studio solution):
|
||||
</p>
|
||||
<pre class="codecanvas">
|
||||
sudo apt-get install g++ make automake autoconf libtool
|
||||
</pre>
|
||||
<p>
|
||||
Install required dependent packages:
|
||||
</p>
|
||||
<pre class="codecanvas">
|
||||
sudo apt-get install libxml2 libxml2-dev libxml2-utils libaprutil1 libaprutil1-dev apache2-prefork-dev
|
||||
</pre>
|
||||
<p>
|
||||
Download mod_security source code from <a href="https://github.com/mihaipitu/ModSecurity">GitHub</a>, compile and install:
|
||||
</p>
|
||||
<pre class="codecanvas">
|
||||
cd mod_security/
|
||||
./autogen.sh
|
||||
./configure --enable-java-module
|
||||
make
|
||||
</pre>
|
||||
<p>
|
||||
Copy compiled library in a convenient folder:
|
||||
</p>
|
||||
<pre class="codecanvas">
|
||||
sudo cp ./java/.libs/libModSecurityJNI.so /usr/lib/
|
||||
</pre>
|
||||
|
||||
|
||||
<br />
|
||||
<h3>Java Web Applications with ModSecurity Filter</h3>
|
||||
<p>
|
||||
ModSecurity for Java uses <a href="http://www.oracle.com/technetwork/java/filters-137243.html">Java Filters</a> in order to
|
||||
intercept Http requests and responses. <b>ModsecurityTestApp</b> is an example of Java EE Web application using the ModSecurity
|
||||
@ -113,12 +140,38 @@
|
||||
|
||||
<p>
|
||||
The ModSecurity Filter makes use of the native libraries written in C/C++ using the JNI technology.
|
||||
As stated earlier, the native libraries are loaded by the <span class="code">ModSecurityLoader.jar</span>
|
||||
which should be loaded by the server at start-up. If you are unable to configure the server to load the
|
||||
ModSecurity libraries at startup, you may load them in your web application although this is not
|
||||
recommended because this will raise <span class="code">UnsatisfiedLinkError</span> if the ModSecurity
|
||||
Filter is used in multiple applications within the same server.
|
||||
There are two ways of loading native libraries by Java Web Applications:
|
||||
<ol>
|
||||
<li>
|
||||
<h4>Loading native libraries directly in the ModSecurityFilter</h4>
|
||||
<p>
|
||||
Although this is the easier, this is not recommended because the JVM will raise
|
||||
<span class="code">UnsatisfiedLinkError</span> if the ModSecurity Filter is used in
|
||||
multiple applications within the same server.
|
||||
The libraries are loaded in the <a class="code" href="../src/java/org/modsecurity/ModSecurity.java">ModSecurity</a> class using
|
||||
<span class="code">System.loadLibrary()</span>. In this case the server has to be started with
|
||||
the following VM options:
|
||||
</p>
|
||||
<pre class="codecanvas">
|
||||
-Djava.library.path=/path/to/libraries/folder/
|
||||
</pre>
|
||||
<p>
|
||||
You can specify multiple folders for the <span class="code">java.library.path</span> variable by using
|
||||
: (colon) or ; (semi-colon), depending on your environment.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<h4>Loading native libraries when the Web Server starts</h4>
|
||||
<p>
|
||||
<a class="code" href="../../ModSecurityLoader/dist/ModSecurityLoader.jar">ModSecurityLoader.jar</a> should be placed
|
||||
in the Java server library loader folder (for example, in Tomcat 7: <span class="code">$CATALINA_HOME/lib</span>).
|
||||
You can build or modify the load directory of <span class="code">ModSecurityLoader</span> from
|
||||
<span class="code">/mod_security/java/ModSecurityLoader/src/</span>.
|
||||
</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
|
797
java/org_modsecurity_ModSecurity.c
Normal file
797
java/org_modsecurity_ModSecurity.c
Normal file
@ -0,0 +1,797 @@
|
||||
#undef inline
|
||||
#define inline __inline
|
||||
|
||||
#include "org_modsecurity_ModSecurity.h"
|
||||
#include "api.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define MODSECURITY_JAVACLASS "org/modsecurity/ModSecurity"
|
||||
#define SERVLETINPUTSTREAM_JAVACLASS "javax/servlet/ServletInputStream"
|
||||
|
||||
#define TOSTRING_MET "toString"
|
||||
#define STRINGRETURN_SIG "()Ljava/lang/String;"
|
||||
|
||||
#define INPUTSTREAM_READ_MET "read"
|
||||
#define INPUTSTREAM_READ_SIG "([BII)I"
|
||||
|
||||
#define MODSECURITY_LOG_MET "log"
|
||||
#define MODSECURITY_LOG_SIG "(ILjava/lang/String;)V"
|
||||
|
||||
#define MODSECURITY__HTTPREQHEADERS_MET "getHttpRequestHeaders"
|
||||
#define MODSECURITY__HTTPREQHEADERS_SIG "(Ljavax/servlet/http/HttpServletRequest;)[[Ljava/lang/String;"
|
||||
#define MODSECURITY__HTTPRESHEADERS_MET "getHttpResponseHeaders"
|
||||
#define MODSECURITY__HTTPRESHEADERS_SIG "(Ljavax/servlet/http/HttpServletResponse;)[[Ljava/lang/String;"
|
||||
#define MODSECURITY__ISPV6_MET "isIPv6"
|
||||
#define MODSECURITY__ISPV6_SIG "(Ljava/lang/String;)Z"
|
||||
|
||||
#define HTTPTRANSACTION_HTTPREQUEST_MET "getHttpRequest"
|
||||
#define HTTPTRANSACTION_HTTPREQUEST_SIG "()Ljavax/servlet/http/HttpServletRequest;"
|
||||
#define HTTPTRANSACTION_MSHTTPREQUEST_MET "getMsHttpRequest"
|
||||
#define HTTPTRANSACTION_MSHTTPREQUEST_SIG "()Lorg/modsecurity/MsHttpServletRequest;"
|
||||
#define HTTPTRANSACTION_MSHTTPRESPONSE_MET "getMsHttpResponse"
|
||||
#define HTTPTRANSACTION_MSHTTPRESPONSE_SIG "()Lorg/modsecurity/MsHttpServletResponse;"
|
||||
|
||||
#define HTTPTRANSACTION_TRANSACTIONID_MET "getTransactionID"
|
||||
|
||||
#define SERVLETREQUEST_SERVERNAME_MET "getServerName"
|
||||
#define SERVLETREQUEST_CHARENCODING_MET "getCharacterEncoding"
|
||||
#define SERVLETREQUEST_CONTENTTYPE_MET "getContentType"
|
||||
#define SERVLETREQUEST_SERVERPORT_MET "getServerPort"
|
||||
#define SERVLETREQUEST_SERVERPORT_SIG "()I"
|
||||
#define SERVLETREQUEST_REMOTEADDR_MET "getRemoteAddr"
|
||||
|
||||
#define SERVLETREQUEST_INPUTSTREAM_MET "getInputStream"
|
||||
#define SERVLETREQUEST_INPUTSTREAM_SIG "()Ljavax/servlet/ServletInputStream;"
|
||||
|
||||
#define HTTPSERVLETREQUEST_PATHINFO_MET "getPathInfo"
|
||||
#define HTTPSERVLETREQUEST_QUERYSTRING_MET "getQueryString"
|
||||
#define HTTPSERVLETREQUEST_METHOD_MET "getMethod"
|
||||
#define HTTPSERVLETREQUEST_PROTOCOL_MET "getProtocol"
|
||||
|
||||
#define HTTPSERVLETREQUEST_REQUESTURL_MET "getRequestURL"
|
||||
#define HTTPSERVLETREQUEST_REQUESTURL_SIG "()Ljava/lang/StringBuffer;"
|
||||
|
||||
#define MSHTTPSERVLETREQUEST_READBODY_MET "readBody"
|
||||
#define MSHTTPSERVLETREQUEST_READBODY_SIG "(I)V"
|
||||
#define MSHTTPSERVLETREQUEST_SETBODY_MET "setBodyBytes"
|
||||
#define MSHTTPSERVLETREQUEST_SETBODY_SIG "([B)V"
|
||||
|
||||
#define SERVLETRESPONSE_CONTENTTYPE_MET "getContentType"
|
||||
#define SERVLETRESPONSE_CHARENCODING_MET "getCharacterEncoding"
|
||||
|
||||
#define MSSERVLETRESPONSE_OUTPUTSTREAM_MET "getByteArrayStream"
|
||||
#define MSSERVLETRESPONSE_OUTPUTSTREAM_SIG "()Ljava/io/ByteArrayInputStream;"
|
||||
|
||||
|
||||
//typedef struct {
|
||||
JavaVM *jvm;
|
||||
jobject modSecurityInstance;
|
||||
directory_config *config;
|
||||
//} JavaModSecurityContext;
|
||||
jmethodID logMethod;
|
||||
|
||||
|
||||
apr_table_t *requests;
|
||||
apr_pool_t *requestsPool;
|
||||
char *serverHostname;
|
||||
|
||||
#define JAVASERVLET_INSTREAM "MSReqBStr"
|
||||
#define JAVASERVLET_OUTSTREAM "MSResBStr"
|
||||
#define JAVASERVLET_TRANSACTION "MSTran"
|
||||
|
||||
void storeJavaServletContext(request_rec *r, const char *key, jobject obj)
|
||||
{
|
||||
apr_table_setn(r->notes, key, (const char *)obj);
|
||||
}
|
||||
|
||||
void removeJavaServletContext(request_rec *r, const char *key)
|
||||
{
|
||||
apr_table_unset(r->notes, key);
|
||||
}
|
||||
|
||||
jobject getJavaServletContext(request_rec *r, const char *key)
|
||||
{
|
||||
jobject obj = NULL;
|
||||
request_rec *rx = NULL;
|
||||
|
||||
/* Look in the current request first. */
|
||||
obj = (jobject)apr_table_get(r->notes, key);
|
||||
if (obj != NULL)
|
||||
return obj;
|
||||
|
||||
/* If this is a subrequest then look in the main request. */
|
||||
if (r->main != NULL)
|
||||
{
|
||||
obj = (jobject)apr_table_get(r->main->notes, key);
|
||||
if (obj != NULL)
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the request was redirected then look in the previous requests. */
|
||||
rx = r->prev;
|
||||
while(rx != NULL)
|
||||
{
|
||||
obj = (jobject)apr_table_get(rx->notes, key);
|
||||
if (obj != NULL)
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
rx = rx->prev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
apr_sockaddr_t *CopySockAddr(jclass msClass, JNIEnv *env, apr_pool_t *pool, char *addrstr, jstring addrStrJstr)
|
||||
{
|
||||
jmethodID isIPv6Met = (*env)->GetStaticMethodID(env, msClass, MODSECURITY__ISPV6_MET, MODSECURITY__ISPV6_SIG);
|
||||
jboolean isIPv6 = (*env)->CallStaticBooleanMethod(env, msClass, isIPv6Met, addrStrJstr);
|
||||
|
||||
apr_sockaddr_t *addr = (apr_sockaddr_t *)apr_palloc(pool, sizeof(apr_sockaddr_t));
|
||||
int adrlen = 16, iplen = 4;
|
||||
|
||||
if(isIPv6)
|
||||
{
|
||||
adrlen = 46;
|
||||
iplen = 16;
|
||||
addr->family = AF_INET6;
|
||||
}
|
||||
else
|
||||
addr->family = AF_INET;
|
||||
|
||||
addr->addr_str_len = adrlen;
|
||||
|
||||
|
||||
addr->hostname = (char*) "unknown";
|
||||
#ifdef WIN32
|
||||
addr->ipaddr_len = sizeof(IN_ADDR);
|
||||
#else
|
||||
addr->ipaddr_len = sizeof(struct in_addr);
|
||||
#endif
|
||||
addr->ipaddr_ptr = &addr->sa.sin.sin_addr;
|
||||
addr->pool = pool;
|
||||
addr->port = 80;
|
||||
#ifdef WIN32
|
||||
memcpy(&addr->sa.sin.sin_addr.S_un.S_addr, addrstr, iplen);
|
||||
#else
|
||||
memcpy(&addr->sa.sin.sin_addr.s_addr, addrstr, iplen);
|
||||
#endif
|
||||
addr->sa.sin.sin_family = addr->family;
|
||||
addr->sa.sin.sin_port = 80;
|
||||
addr->salen = sizeof(addr->sa);
|
||||
addr->servname = addr->hostname;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
inline char* fromJString(JNIEnv *env, jstring jStr, apr_pool_t *pool)
|
||||
{
|
||||
char *str;
|
||||
if (jStr != NULL)
|
||||
{
|
||||
const char *jCStr = (*env)->GetStringUTFChars(env, jStr, NULL);
|
||||
int len = strlen(jCStr);
|
||||
str = (char*) apr_palloc(pool, len + 1);
|
||||
memcpy(str, jCStr, len);
|
||||
str[len] = '\0'; //null terminate
|
||||
(*env)->ReleaseStringUTFChars(env, jStr, jCStr); //release java memory
|
||||
}
|
||||
else
|
||||
str = (char*) "";
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
inline char* fromJStringMethod(JNIEnv *env, jmethodID method, jobject obj, apr_pool_t *pool)
|
||||
{
|
||||
jstring jStr = (jstring) (*env)->CallObjectMethod(env, obj, method);
|
||||
|
||||
return fromJString(env, jStr, pool);
|
||||
}
|
||||
|
||||
|
||||
void logSec(void *obj, int level, char *str)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jstring jStr;
|
||||
|
||||
if (!(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL)) //get the Enviroment from the JavaVM
|
||||
{
|
||||
jStr = (*env)->NewStringUTF(env, str);
|
||||
|
||||
(*env)->CallVoidMethod(env, modSecurityInstance, logMethod, level, jStr);
|
||||
|
||||
(*jvm)->DetachCurrentThread(jvm);
|
||||
//in the context of a JVM thread, any leaked local references are automatically cleaned up
|
||||
//(*env)->ReleaseStringUTFChars(jStr, str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
apr_status_t ReadBodyCallback(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos)
|
||||
{
|
||||
jobject inputStream = getJavaServletContext(r, JAVASERVLET_INSTREAM); //servlet request input stream
|
||||
JNIEnv *env;
|
||||
|
||||
*readcnt = 0;
|
||||
|
||||
if(inputStream == NULL)
|
||||
{
|
||||
*is_eos = 1;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
if (!(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL))
|
||||
{
|
||||
//read request body from the servlet input stream using 'read' method
|
||||
jclass inputStreamClass = (*env)->FindClass(env, SERVLETINPUTSTREAM_JAVACLASS);
|
||||
jmethodID read = (*env)->GetMethodID(env, inputStreamClass, INPUTSTREAM_READ_MET, INPUTSTREAM_READ_SIG);
|
||||
|
||||
jbyteArray byteArrayBuf = (*env)->NewByteArray(env, length);
|
||||
|
||||
jint count = (*env)->CallIntMethod(env, inputStream, read, byteArrayBuf, 0, length);
|
||||
jbyte* bufferPtr = (*env)->GetByteArrayElements(env, byteArrayBuf, NULL);
|
||||
|
||||
if (count == -1 || count > length || (*env)->ExceptionCheck(env) == JNI_TRUE) //end of stream
|
||||
{
|
||||
*is_eos = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*readcnt = count;
|
||||
|
||||
memcpy(buf, bufferPtr, *readcnt);
|
||||
}
|
||||
(*env)->ReleaseByteArrayElements(env, byteArrayBuf, bufferPtr, 0);
|
||||
(*env)->DeleteLocalRef(env, byteArrayBuf);
|
||||
|
||||
(*jvm)->DetachCurrentThread(jvm);
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
apr_status_t WriteBodyCallback(request_rec *r, char *buf, unsigned int length)
|
||||
{
|
||||
jobject httpTransaction;
|
||||
JNIEnv *env;
|
||||
jclass httpTransactionClass;
|
||||
jmethodID getHttpRequest;
|
||||
jobject httpServletRequest;
|
||||
jclass httpServletRequestClass;
|
||||
jmethodID setBodyBytes;
|
||||
jbyte *jbuf;
|
||||
int i;
|
||||
jbyteArray byteArrayBuf;
|
||||
|
||||
|
||||
httpTransaction = getJavaServletContext(r, JAVASERVLET_TRANSACTION);
|
||||
|
||||
if(httpTransaction == NULL)
|
||||
{
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
if (!(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL))
|
||||
{
|
||||
httpTransactionClass = (*env)->GetObjectClass(env, httpTransaction);
|
||||
|
||||
getHttpRequest = (*env)->GetMethodID(env, httpTransactionClass, HTTPTRANSACTION_MSHTTPREQUEST_MET, HTTPTRANSACTION_MSHTTPREQUEST_SIG);
|
||||
httpServletRequest = (*env)->CallObjectMethod(env, httpTransaction, getHttpRequest);
|
||||
|
||||
httpServletRequestClass = (*env)->GetObjectClass(env, httpServletRequest);
|
||||
setBodyBytes = (*env)->GetMethodID(env, httpServletRequestClass, MSHTTPSERVLETREQUEST_SETBODY_MET, MSHTTPSERVLETREQUEST_SETBODY_SIG);
|
||||
|
||||
jbuf = (jbyte*) apr_palloc(requestsPool, sizeof(jbyte) * length);
|
||||
for (i = 0; i < length; i++)
|
||||
jbuf[i] = buf[i];
|
||||
|
||||
byteArrayBuf = (*env)->NewByteArray(env, length);
|
||||
(*env)->SetByteArrayRegion(env, byteArrayBuf, 0, length, jbuf);
|
||||
|
||||
//on setBodyBytes we copy buf bytes
|
||||
(*env)->CallVoidMethod(env, httpServletRequest, setBodyBytes, byteArrayBuf);
|
||||
|
||||
//(*env)->ReleaseByteArrayElements(byteArrayBuf, jbuf, NULL);
|
||||
|
||||
(*jvm)->DetachCurrentThread(jvm);
|
||||
}
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
apr_status_t ReadResponseCallback(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos)
|
||||
{
|
||||
jobject inputStream;
|
||||
JNIEnv *env;
|
||||
jclass inputStreamClass;
|
||||
jmethodID read;
|
||||
jbyteArray byteArrayBuf;
|
||||
jint count;
|
||||
jbyte* bufferPtr;
|
||||
|
||||
|
||||
inputStream = getJavaServletContext(r, JAVASERVLET_OUTSTREAM);
|
||||
*readcnt = 0;
|
||||
|
||||
if(inputStream == NULL)
|
||||
{
|
||||
*is_eos = 1;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
if (!(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL))
|
||||
{
|
||||
inputStreamClass = (*env)->GetObjectClass(env, inputStream);
|
||||
read = (*env)->GetMethodID(env, inputStreamClass, INPUTSTREAM_READ_MET, INPUTSTREAM_READ_SIG);
|
||||
|
||||
byteArrayBuf = (*env)->NewByteArray(env, length);
|
||||
|
||||
count = (*env)->CallIntMethod(env, inputStream, read, byteArrayBuf, 0, length);
|
||||
bufferPtr = (*env)->GetByteArrayElements(env, byteArrayBuf, NULL);
|
||||
|
||||
if (count == -1 || count > length || (*env)->ExceptionCheck(env) == JNI_TRUE) //end of stream
|
||||
{
|
||||
*is_eos = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*readcnt = count;
|
||||
|
||||
memcpy(buf, bufferPtr, *readcnt);
|
||||
}
|
||||
(*env)->ReleaseByteArrayElements(env, byteArrayBuf, bufferPtr, 0);
|
||||
(*env)->DeleteLocalRef(env, byteArrayBuf);
|
||||
|
||||
(*jvm)->DetachCurrentThread(jvm);
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
apr_status_t WriteResponseCallback(request_rec *r, char *buf, unsigned int length)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jbyteArray byteArrayBuf;
|
||||
jclass httpTransactionClass;
|
||||
jmethodID getHttpResponse;
|
||||
jobject httpServletResponse;
|
||||
jbyte *jbuf;
|
||||
int i;
|
||||
jmethodID setBodyBytes;
|
||||
jclass httpServletResponseClass;
|
||||
jobject httpTransaction = getJavaServletContext(r, JAVASERVLET_TRANSACTION);
|
||||
|
||||
if(httpTransaction == NULL)
|
||||
{
|
||||
(*jvm)->DetachCurrentThread(jvm);
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
if (!(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL))
|
||||
{
|
||||
httpTransactionClass = (*env)->GetObjectClass(env, httpTransaction);
|
||||
|
||||
getHttpResponse = (*env)->GetMethodID(env, httpTransactionClass, HTTPTRANSACTION_MSHTTPRESPONSE_MET, HTTPTRANSACTION_MSHTTPRESPONSE_SIG);
|
||||
httpServletResponse = (*env)->CallObjectMethod(env, httpTransaction, getHttpResponse);
|
||||
|
||||
|
||||
httpServletResponseClass = (*env)->GetObjectClass(env, httpServletResponse);
|
||||
setBodyBytes = (*env)->GetMethodID(env, httpServletResponseClass, MSHTTPSERVLETREQUEST_SETBODY_MET, MSHTTPSERVLETREQUEST_SETBODY_SIG);
|
||||
|
||||
jbuf = (jbyte*) apr_palloc(requestsPool, sizeof(jbyte) * length);
|
||||
for (i = 0; i < length; i++)
|
||||
jbuf[i] = buf[i];
|
||||
|
||||
byteArrayBuf = (*env)->NewByteArray(env, length);
|
||||
(*env)->SetByteArrayRegion(env, byteArrayBuf, 0, length, jbuf);
|
||||
|
||||
//on setBodyBytes we copy buf bytes
|
||||
(*env)->CallVoidMethod(env, httpServletResponse, setBodyBytes, byteArrayBuf);
|
||||
|
||||
//(*env)->ReleaseByteArrayElements(byteArrayBuf, jbuf, NULL);
|
||||
|
||||
(*jvm)->DetachCurrentThread(jvm);
|
||||
}
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_initialize(JNIEnv *env, jobject obj, jstring serverName)
|
||||
{
|
||||
(*env)->GetJavaVM(env, &jvm);
|
||||
modSecurityInstance = (*env)->NewGlobalRef(env, obj); //Save the ModSecurity object for further use
|
||||
|
||||
logMethod = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, obj), MODSECURITY_LOG_MET, MODSECURITY_LOG_SIG); //log method ID
|
||||
|
||||
modsecSetLogHook(NULL, logSec);
|
||||
|
||||
modsecSetReadBody(ReadBodyCallback);
|
||||
modsecSetReadResponse(ReadResponseCallback);
|
||||
modsecSetWriteBody(WriteBodyCallback);
|
||||
modsecSetWriteResponse(WriteResponseCallback);
|
||||
|
||||
modsecInit();
|
||||
|
||||
modsecStartConfig();
|
||||
config = modsecGetDefaultConfig();
|
||||
modsecFinalizeConfig();
|
||||
modsecInitProcess();
|
||||
config = NULL;
|
||||
|
||||
//table for requests
|
||||
apr_pool_create(&requestsPool, NULL);
|
||||
requests = apr_table_make(requestsPool, 10);
|
||||
|
||||
serverHostname = fromJString(env, serverName, requestsPool);
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_destroy(JNIEnv *env, jobject obj)
|
||||
{
|
||||
(*env)->DeleteGlobalRef(env, modSecurityInstance);
|
||||
|
||||
apr_pool_destroy(requestsPool);
|
||||
|
||||
modsecTerminate();
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
inline void setHeaders(JNIEnv *env, jclass httpServletRequestClass, jobject httpServletR, apr_table_t *reqHeaders, apr_pool_t *pool, const char *headersMet, const char *headersSig)
|
||||
{
|
||||
jmethodID getHttpHeaders;
|
||||
jobjectArray headersTable;
|
||||
jsize size;
|
||||
int i;
|
||||
|
||||
//All headers are returned in a table by a static method from ModSecurity class
|
||||
getHttpHeaders = (*env)->GetStaticMethodID(env, httpServletRequestClass, headersMet, headersSig);
|
||||
headersTable = (jobjectArray) (*env)->CallStaticObjectMethod(env, httpServletRequestClass, getHttpHeaders, httpServletR);
|
||||
size = (*env)->GetArrayLength(env, headersTable);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
const char *headerName;
|
||||
const char *headerValue;
|
||||
jobjectArray row = (jobjectArray) (*env)->GetObjectArrayElement(env, headersTable, i);
|
||||
jstring headerNameJStr = (jstring) (*env)->GetObjectArrayElement(env, row, 0);
|
||||
jstring headerValueJStr = (jstring) (*env)->GetObjectArrayElement(env, row, 1);
|
||||
|
||||
if (headerNameJStr != NULL && headerValueJStr != NULL)
|
||||
{
|
||||
headerName = fromJString(env, headerNameJStr, pool);
|
||||
//apr_pool_cleanup_register(r->pool, headerName, memCleanup, apr_pool_cleanup_null);
|
||||
|
||||
headerValue = fromJString(env, headerValueJStr, pool);
|
||||
//apr_pool_cleanup_register(r->pool, headerValue, memCleanup, apr_pool_cleanup_null);
|
||||
|
||||
apr_table_setn(reqHeaders, headerName, headerValue);
|
||||
|
||||
(*env)->DeleteLocalRef(env, headerNameJStr);
|
||||
(*env)->DeleteLocalRef(env, headerValueJStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_onRequest(JNIEnv *env, jobject obj, jstring configPath, jobject httpTransaction, jboolean reloadConfig)
|
||||
{
|
||||
conn_rec *c;
|
||||
request_rec *r;
|
||||
const char *err;
|
||||
jmethodID getHttpRequest;
|
||||
jclass httpTransactionClass;
|
||||
jobject httpServletRequest;
|
||||
jobject servletRequest;
|
||||
jclass httpServletRequestClass;
|
||||
jclass servletRequestClass;
|
||||
jclass modSecurityClass;
|
||||
jmethodID readBody;
|
||||
jmethodID getTransactionID;
|
||||
jmethodID getInputStream;
|
||||
const char *reqID;
|
||||
jobject inputStream;
|
||||
jmethodID getServerName;
|
||||
jmethodID getServerPort;
|
||||
int port;
|
||||
char *port_str;
|
||||
jmethodID getPathInfo;
|
||||
jmethodID getQueryString;
|
||||
jmethodID getCharacterEncoding;
|
||||
jmethodID getContentType;
|
||||
const char *lng;
|
||||
jmethodID getMethod;
|
||||
const char* method;
|
||||
jmethodID getProtocol;
|
||||
jmethodID getRequestURL;
|
||||
jobject stringBuffer;
|
||||
jmethodID toStringBuff;
|
||||
char *url;
|
||||
jmethodID getRemoteAddr;
|
||||
jstring remoteAddrJStr;
|
||||
char *remoteAddr;
|
||||
int status;
|
||||
int len;
|
||||
|
||||
if (config == NULL || reloadConfig)
|
||||
{
|
||||
const char *path;
|
||||
config = modsecGetDefaultConfig();
|
||||
path = fromJString(env, configPath, config->mp); //path to modsecurity.conf
|
||||
|
||||
err = modsecProcessConfig(config, path, NULL);
|
||||
|
||||
if(err != NULL)
|
||||
{
|
||||
logSec(NULL, 0, (char*)err);
|
||||
|
||||
return DONE;
|
||||
}
|
||||
}
|
||||
|
||||
c = modsecNewConnection();
|
||||
modsecProcessConnection(c);
|
||||
r = modsecNewRequest(c, config);
|
||||
|
||||
r->server->server_hostname = serverHostname;
|
||||
httpTransactionClass = (*env)->GetObjectClass(env, httpTransaction);
|
||||
getHttpRequest = (*env)->GetMethodID(env, httpTransactionClass, HTTPTRANSACTION_MSHTTPREQUEST_MET, HTTPTRANSACTION_MSHTTPREQUEST_SIG);
|
||||
|
||||
httpServletRequest = (*env)->CallObjectMethod(env, httpTransaction, getHttpRequest);
|
||||
servletRequest = httpServletRequest; //superclass of HttpServletRequest
|
||||
|
||||
httpServletRequestClass = (*env)->GetObjectClass(env, httpServletRequest); //MsHttpServletRequest interface
|
||||
servletRequestClass = (*env)->GetObjectClass(env, servletRequest); //ServletRequest interface
|
||||
modSecurityClass = (*env)->GetObjectClass(env, obj); //ModSecurity class
|
||||
|
||||
//readBody method reads all bytes from the inputStream or a maximum of 'config->reqbody_limit' bytes
|
||||
readBody = (*env)->GetMethodID(env, httpServletRequestClass, MSHTTPSERVLETREQUEST_READBODY_MET, MSHTTPSERVLETREQUEST_READBODY_SIG);
|
||||
(*env)->CallVoidMethod(env, httpServletRequest, readBody, config->reqbody_limit);
|
||||
|
||||
if ((*env)->ExceptionCheck(env) == JNI_TRUE) //read body raised an Exception, return to JVM
|
||||
{
|
||||
modsecFinishRequest(r);
|
||||
return DONE;
|
||||
}
|
||||
|
||||
|
||||
getTransactionID = (*env)->GetMethodID(env, httpTransactionClass, HTTPTRANSACTION_TRANSACTIONID_MET, STRINGRETURN_SIG);
|
||||
reqID = fromJStringMethod(env, getTransactionID, httpTransaction, r->pool); //fromJString(env, requestID, r->pool); //unique ID of this request
|
||||
apr_table_setn(requests, reqID, (const char*) r); //store this request for response processing
|
||||
|
||||
|
||||
getInputStream = (*env)->GetMethodID(env, httpServletRequestClass, SERVLETREQUEST_INPUTSTREAM_MET, SERVLETREQUEST_INPUTSTREAM_SIG);
|
||||
inputStream = (*env)->CallObjectMethod(env, httpServletRequest, getInputStream); //Request body input stream used in the read body callback
|
||||
|
||||
storeJavaServletContext(r, JAVASERVLET_INSTREAM, inputStream);
|
||||
storeJavaServletContext(r, JAVASERVLET_TRANSACTION, httpTransaction);
|
||||
|
||||
|
||||
getServerName = (*env)->GetMethodID(env, servletRequestClass, SERVLETREQUEST_SERVERNAME_MET, STRINGRETURN_SIG);
|
||||
r->hostname = fromJStringMethod(env, getServerName, servletRequest, r->pool);
|
||||
|
||||
getServerPort = (*env)->GetMethodID(env, servletRequestClass, SERVLETREQUEST_SERVERPORT_MET, SERVLETREQUEST_SERVERPORT_SIG);
|
||||
port = (*env)->CallIntMethod(env, servletRequest, getServerPort); //server port
|
||||
port_str = apr_itoa(r->pool, port);
|
||||
|
||||
|
||||
getPathInfo = (*env)->GetMethodID(env, httpServletRequestClass, HTTPSERVLETREQUEST_PATHINFO_MET, STRINGRETURN_SIG);
|
||||
r->path_info = fromJStringMethod(env, getPathInfo, httpServletRequest, r->pool);
|
||||
|
||||
|
||||
getQueryString = (*env)->GetMethodID(env, httpServletRequestClass, HTTPSERVLETREQUEST_QUERYSTRING_MET, STRINGRETURN_SIG);
|
||||
r->args = fromJStringMethod(env, getQueryString, httpServletRequest, r->pool);
|
||||
|
||||
|
||||
setHeaders(env, httpServletRequestClass, httpServletRequest, r->headers_in, r->pool, MODSECURITY__HTTPREQHEADERS_MET, MODSECURITY__HTTPREQHEADERS_SIG);
|
||||
|
||||
|
||||
getCharacterEncoding = (*env)->GetMethodID(env, servletRequestClass, SERVLETREQUEST_CHARENCODING_MET, STRINGRETURN_SIG);
|
||||
r->content_encoding = fromJStringMethod(env, getCharacterEncoding, servletRequest, r->pool);
|
||||
|
||||
|
||||
getContentType = (*env)->GetMethodID(env, servletRequestClass, SERVLETREQUEST_CONTENTTYPE_MET, STRINGRETURN_SIG);
|
||||
r->content_type = fromJStringMethod(env, getContentType, servletRequest, r->pool);
|
||||
|
||||
|
||||
lng = apr_table_get(r->headers_in, "Content-Languages");
|
||||
if(lng != NULL)
|
||||
{
|
||||
r->content_languages = apr_array_make(r->pool, 1, sizeof(const char *));
|
||||
*(const char **)apr_array_push(r->content_languages) = lng;
|
||||
}
|
||||
|
||||
getMethod = (*env)->GetMethodID(env, httpServletRequestClass, HTTPSERVLETREQUEST_METHOD_MET, STRINGRETURN_SIG);
|
||||
method = fromJStringMethod(env, getMethod, httpServletRequest, r->pool);
|
||||
|
||||
//#define SETMETHOD(m) if(strcmp(method,#m) == 0){ r->method = method; r->method_number = M_##m; }
|
||||
|
||||
r->method = "INVALID";
|
||||
r->method_number = M_INVALID;
|
||||
|
||||
//might be faster with elseif
|
||||
if (strcmp(method, "OPTIONS") == 0) { r->method = method; r->method_number = M_OPTIONS; }
|
||||
else if (strcmp(method, "GET") == 0) { r->method = method; r->method_number = M_GET; }
|
||||
else if (strcmp(method, "POST") == 0) { r->method = method; r->method_number = M_POST; }
|
||||
else if (strcmp(method, "PUT") == 0) { r->method = method; r->method_number = M_PUT; }
|
||||
else if (strcmp(method, "DELETE") == 0) { r->method = method; r->method_number = M_DELETE; }
|
||||
else if (strcmp(method, "TRACE") == 0) { r->method = method; r->method_number = M_TRACE; }
|
||||
else if (strcmp(method, "CONNECT") == 0) { r->method = method; r->method_number = M_CONNECT; }
|
||||
else if (strcmp(method, "MOVE") == 0) { r->method = method; r->method_number = M_MOVE; }
|
||||
else if (strcmp(method, "COPY") == 0) { r->method = method; r->method_number = M_COPY; }
|
||||
else if (strcmp(method, "PROPFIND") == 0) { r->method = method; r->method_number = M_PROPFIND; }
|
||||
else if (strcmp(method, "PROPPATCH") == 0) { r->method = method; r->method_number = M_PROPPATCH; }
|
||||
else if (strcmp(method, "MKCOL") == 0) { r->method = method; r->method_number = M_MKCOL; }
|
||||
else if (strcmp(method, "LOCK") == 0) { r->method = method; r->method_number = M_LOCK; }
|
||||
else if (strcmp(method, "UNLOCK") == 0) { r->method = method; r->method_number = M_UNLOCK; }
|
||||
|
||||
getProtocol = (*env)->GetMethodID(env, httpServletRequestClass, HTTPSERVLETREQUEST_PROTOCOL_MET, STRINGRETURN_SIG);
|
||||
r->protocol = fromJStringMethod(env, getProtocol, httpServletRequest, r->pool);
|
||||
|
||||
r->request_time = apr_time_now();
|
||||
|
||||
r->parsed_uri.scheme = (char*) "http";
|
||||
r->parsed_uri.path = r->path_info;
|
||||
r->parsed_uri.hostname = (char *)r->hostname;
|
||||
r->parsed_uri.is_initialized = 1;
|
||||
r->parsed_uri.port = port;
|
||||
r->parsed_uri.port_str = port_str;
|
||||
r->parsed_uri.query = r->args;
|
||||
r->parsed_uri.dns_looked_up = 0;
|
||||
r->parsed_uri.dns_resolved = 0;
|
||||
r->parsed_uri.password = NULL;
|
||||
r->parsed_uri.user = NULL;
|
||||
r->parsed_uri.fragment = NULL;
|
||||
|
||||
|
||||
//the request Url is in a StringBuffer object
|
||||
getRequestURL = (*env)->GetMethodID(env, httpServletRequestClass, HTTPSERVLETREQUEST_REQUESTURL_MET, HTTPSERVLETREQUEST_REQUESTURL_SIG);
|
||||
stringBuffer = (*env)->CallObjectMethod(env, httpServletRequest, getRequestURL);
|
||||
if (stringBuffer != NULL)
|
||||
{
|
||||
toStringBuff = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, stringBuffer), TOSTRING_MET, STRINGRETURN_SIG);
|
||||
url = fromJStringMethod(env, toStringBuff, stringBuffer, r->pool);
|
||||
|
||||
if (strcmp(r->args, "") != 0)
|
||||
{
|
||||
len = strlen(url) + 1 + strlen(r->args) + 1;
|
||||
r->unparsed_uri = (char*)apr_palloc(r->pool, len); //unparsed uri with full query
|
||||
strcpy(r->unparsed_uri, url);
|
||||
strcat(r->unparsed_uri, "?");
|
||||
strcat(r->unparsed_uri, r->args);
|
||||
r->unparsed_uri[len] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
r->unparsed_uri = url;
|
||||
}
|
||||
r->uri = r->unparsed_uri;
|
||||
}
|
||||
|
||||
len = strlen(r->method) + 1 + strlen(r->uri) + 1 + strlen(r->protocol) + 1;
|
||||
r->the_request = (char *)apr_palloc(r->pool, len);
|
||||
|
||||
strcpy(r->the_request, r->method);
|
||||
strcat(r->the_request, " ");
|
||||
strcat(r->the_request, r->uri);
|
||||
strcat(r->the_request, " ");
|
||||
strcat(r->the_request, r->protocol);
|
||||
r->the_request[len] = 0;
|
||||
|
||||
apr_table_setn(r->subprocess_env, "UNIQUE_ID", reqID);
|
||||
|
||||
getRemoteAddr = (*env)->GetMethodID(env, servletRequestClass, SERVLETREQUEST_REMOTEADDR_MET, STRINGRETURN_SIG);
|
||||
remoteAddrJStr = (jstring) (*env)->CallObjectMethod(env, servletRequest, getRemoteAddr);
|
||||
remoteAddr = fromJString(env, remoteAddrJStr, r->pool);
|
||||
//apr_pool_cleanup_register(r->pool, remoteAddr, memCleanup, apr_pool_cleanup_null);
|
||||
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3
|
||||
c->remote_addr = CopySockAddr(modSecurityClass, env, r->pool, remoteAddr, remoteAddrJStr);
|
||||
c->remote_ip = remoteAddr;
|
||||
#else
|
||||
c->client_addr = CopySockAddr(modSecurityClass, env, r->pool, remoteAddr, remoteAddrJStr);
|
||||
c->client_ip = remoteAddr;
|
||||
#endif
|
||||
c->remote_host = NULL;
|
||||
|
||||
status = modsecProcessRequest(r);
|
||||
|
||||
removeJavaServletContext(r, JAVASERVLET_INSTREAM);
|
||||
removeJavaServletContext(r, JAVASERVLET_TRANSACTION);
|
||||
|
||||
if (status != DECLINED) //Java modsecurityFilter blocks the request, onResponse will not be called, it's safe to finish the request
|
||||
{
|
||||
apr_table_unset(requests, reqID);
|
||||
modsecFinishRequest(r);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_onResponse(JNIEnv *env, jobject obj, jobject httpTransaction)
|
||||
{
|
||||
jclass httpTransactionClass;
|
||||
jmethodID getTransactionID;
|
||||
jstring reqIDjStr;
|
||||
const char *reqID;
|
||||
request_rec *r;
|
||||
jmethodID getHttpResponse;
|
||||
jobject httpServletResponse;
|
||||
jclass httpServletResponseClass;
|
||||
jmethodID getOutputStream;
|
||||
jobject responseStream;
|
||||
jmethodID getContentType;
|
||||
jmethodID getCharEncoding;
|
||||
char *ct;
|
||||
const char *lng;
|
||||
int status;
|
||||
|
||||
|
||||
httpTransactionClass = (*env)->GetObjectClass(env, httpTransaction);
|
||||
|
||||
getTransactionID = (*env)->GetMethodID(env, httpTransactionClass, HTTPTRANSACTION_TRANSACTIONID_MET, STRINGRETURN_SIG);
|
||||
reqIDjStr = (jstring) (*env)->CallObjectMethod(env, httpTransaction, getTransactionID);
|
||||
reqID = (*env)->GetStringUTFChars(env, reqIDjStr, NULL);
|
||||
|
||||
r = (request_rec*) apr_table_get(requests, reqID);
|
||||
apr_table_unset(requests, reqID); //remove this request from the requests table
|
||||
(*env)->ReleaseStringUTFChars(env, reqIDjStr, reqID);
|
||||
|
||||
if (r == NULL)
|
||||
{
|
||||
return DONE;
|
||||
}
|
||||
|
||||
getHttpResponse = (*env)->GetMethodID(env, httpTransactionClass, HTTPTRANSACTION_MSHTTPRESPONSE_MET, HTTPTRANSACTION_MSHTTPRESPONSE_SIG);
|
||||
httpServletResponse = (*env)->CallObjectMethod(env, httpTransaction, getHttpResponse);
|
||||
|
||||
httpServletResponseClass = (*env)->GetObjectClass(env, httpServletResponse); //MsHttpServletResponse class
|
||||
//jclass modSecurityClass = (*env)->GetObjectClass(obj); //ModSecurity class
|
||||
|
||||
getOutputStream = (*env)->GetMethodID(env, httpServletResponseClass, MSSERVLETRESPONSE_OUTPUTSTREAM_MET, MSSERVLETRESPONSE_OUTPUTSTREAM_SIG);
|
||||
responseStream = (*env)->CallObjectMethod(env, httpServletResponse, getOutputStream); //Response output stream used in the read response callback
|
||||
|
||||
if ((*env)->ExceptionCheck(env) == JNI_TRUE)
|
||||
{
|
||||
modsecFinishRequest(r);
|
||||
return DONE;
|
||||
}
|
||||
|
||||
storeJavaServletContext(r, JAVASERVLET_TRANSACTION, httpTransaction);
|
||||
storeJavaServletContext(r, JAVASERVLET_OUTSTREAM, responseStream);
|
||||
|
||||
getContentType = (*env)->GetMethodID(env, httpServletResponseClass, SERVLETRESPONSE_CONTENTTYPE_MET, STRINGRETURN_SIG);
|
||||
ct = fromJStringMethod(env, getContentType, httpServletResponse, r->pool);
|
||||
if(strcmp(ct, "") == 0)
|
||||
ct = (char*) "text/html";
|
||||
r->content_type = ct;
|
||||
|
||||
|
||||
getCharEncoding = (*env)->GetMethodID(env, httpServletResponseClass, SERVLETRESPONSE_CHARENCODING_MET, STRINGRETURN_SIG);
|
||||
r->content_encoding = fromJStringMethod(env, getCharEncoding, httpServletResponse, r->pool);
|
||||
|
||||
|
||||
setHeaders(env, httpServletResponseClass, httpServletResponse, r->headers_out, r->pool, MODSECURITY__HTTPRESHEADERS_MET, MODSECURITY__HTTPRESHEADERS_SIG);
|
||||
|
||||
lng = apr_table_get(r->headers_out, "Content-Languages");
|
||||
if(lng != NULL)
|
||||
{
|
||||
r->content_languages = apr_array_make(r->pool, 1, sizeof(const char *));
|
||||
*(const char **)apr_array_push(r->content_languages) = lng;
|
||||
}
|
||||
|
||||
|
||||
status = modsecProcessResponse(r);
|
||||
|
||||
removeJavaServletContext(r, JAVASERVLET_OUTSTREAM);
|
||||
removeJavaServletContext(r, JAVASERVLET_TRANSACTION);
|
||||
modsecFinishRequest(r);
|
||||
|
||||
return status;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user