mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2026-01-01 22:25:45 +03:00
Write request & response callbacks
This commit is contained in:
1
java/.gitignore
vendored
1
java/.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
libs/
|
||||||
Debug/
|
Debug/
|
||||||
Release/
|
Release/
|
||||||
*.sdf
|
*.sdf
|
||||||
|
|||||||
@@ -164,7 +164,7 @@
|
|||||||
<ClCompile Include="..\standalone\hooks.c" />
|
<ClCompile Include="..\standalone\hooks.c" />
|
||||||
<ClCompile Include="..\standalone\regex.c" />
|
<ClCompile Include="..\standalone\regex.c" />
|
||||||
<ClCompile Include="..\standalone\server.c" />
|
<ClCompile Include="..\standalone\server.c" />
|
||||||
<ClCompile Include="org_modsecurity_ModSecurity.c" />
|
<ClCompile Include="org_modsecurity_ModSecurity.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\apache2\acmp.h" />
|
<ClInclude Include="..\apache2\acmp.h" />
|
||||||
|
|||||||
@@ -96,7 +96,6 @@
|
|||||||
<ClCompile Include="..\apache2\msc_tree.c">
|
<ClCompile Include="..\apache2\msc_tree.c">
|
||||||
<Filter>ModSecurity Sources</Filter>
|
<Filter>ModSecurity Sources</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="org_modsecurity_ModSecurity.c" />
|
|
||||||
<ClCompile Include="..\standalone\api.c">
|
<ClCompile Include="..\standalone\api.c">
|
||||||
<Filter>Standalone Sources</Filter>
|
<Filter>Standalone Sources</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -118,6 +117,7 @@
|
|||||||
<ClCompile Include="..\standalone\server.c">
|
<ClCompile Include="..\standalone\server.c">
|
||||||
<Filter>Standalone Sources</Filter>
|
<Filter>Standalone Sources</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="org_modsecurity_ModSecurity.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\apache2\acmp.h">
|
<ClInclude Include="..\apache2\acmp.h">
|
||||||
|
|||||||
4
java/ModSecurityJNI.vcxproj.user
Normal file
4
java/ModSecurityJNI.vcxproj.user
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup />
|
||||||
|
</Project>
|
||||||
@@ -12,18 +12,25 @@ import javax.servlet.ServletException;
|
|||||||
* @author Mihai Pitu
|
* @author Mihai Pitu
|
||||||
*/
|
*/
|
||||||
public final class ModSecurity {
|
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
|
||||||
|
|
||||||
public static final int DONE = -2;
|
public static final int DONE = -2;
|
||||||
public static final int DECLINED = -1;
|
public static final int DECLINED = -1;
|
||||||
public static final int OK = 0;
|
public static final int OK = 0;
|
||||||
//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
|
|
||||||
private FilterConfig filterConfig;
|
private FilterConfig filterConfig;
|
||||||
private String confFilename;
|
private String confFilename;
|
||||||
private long confTime;
|
private long confTime;
|
||||||
private final static String pathToLib = "c:\\work\\mod_security\\java\\Debug\\";
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
//TODO: bad practice, native libraries should be loaded in server's classloader
|
// try {
|
||||||
|
// Class.forName("org.modsecurity.loader.ModSecurityLoader");
|
||||||
|
// System.out.println("MS loader found");
|
||||||
|
// } catch (ClassNotFoundException ex) {
|
||||||
|
// Logger.getLogger(ModSecurity.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//TODO: bad practice (if we have two webapps using ModSecurity, one will raise UnsatisfiedLinkError),
|
||||||
|
//native libraries should be loaded in server's root classloader
|
||||||
System.load("c:\\work\\mod_security\\java\\libs\\zlib1.dll");
|
System.load("c:\\work\\mod_security\\java\\libs\\zlib1.dll");
|
||||||
System.load("c:\\work\\mod_security\\java\\libs\\libxml2.dll");
|
System.load("c:\\work\\mod_security\\java\\libs\\libxml2.dll");
|
||||||
System.load("c:\\work\\mod_security\\java\\libs\\pcre.dll");
|
System.load("c:\\work\\mod_security\\java\\libs\\pcre.dll");
|
||||||
@@ -31,9 +38,6 @@ public final class ModSecurity {
|
|||||||
System.load("c:\\work\\mod_security\\java\\libs\\libapriconv-1.dll");
|
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\\libs\\libaprutil-1.dll");
|
||||||
System.load("c:\\work\\mod_security\\java\\Debug\\ModSecurityJNI.dll");
|
System.load("c:\\work\\mod_security\\java\\Debug\\ModSecurityJNI.dll");
|
||||||
//java.lang.reflect.Field loadedLibraries = ClassLoader.class.getDeclaredField("loadedLibraryNames");
|
|
||||||
//loadedLibraries.setAccessible(true);
|
|
||||||
//final Vector<String> libraries = (Vector<String>) loadedLibraries.get(ClassLoader.getSystemClassLoader());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModSecurity(FilterConfig fc, String confFile) throws ServletException {
|
public ModSecurity(FilterConfig fc, String confFile) throws ServletException {
|
||||||
@@ -41,11 +45,11 @@ public final class ModSecurity {
|
|||||||
this.confFilename = confFile;
|
this.confFilename = confFile;
|
||||||
confTime = new File(confFilename).lastModified();
|
confTime = new File(confFilename).lastModified();
|
||||||
|
|
||||||
this.initialize();
|
this.initialize(fc.getFilterName());
|
||||||
filterConfig.getServletContext().log("ModSecurity started.");
|
filterConfig.getServletContext().log("ModSecurity started.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private native int initialize();
|
private native int initialize(String serverName);
|
||||||
|
|
||||||
public native int destroy();
|
public native int destroy();
|
||||||
|
|
||||||
|
|||||||
@@ -23,10 +23,9 @@ public class ModSecurityFilter implements Filter {
|
|||||||
String confFilename = fc.getInitParameter("conf");
|
String confFilename = fc.getInitParameter("conf");
|
||||||
if (confFilename == null) {
|
if (confFilename == null) {
|
||||||
throw new ServletException("ModSecurity: parameter 'conf' not available in web.xml");
|
throw new ServletException("ModSecurity: parameter 'conf' not available in web.xml");
|
||||||
} else {
|
|
||||||
confFilename = fc.getServletContext().getRealPath(confFilename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
modsecurity = new ModSecurity(fc, confFilename);
|
modsecurity = new ModSecurity(fc, confFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,14 +39,24 @@ public class ModSecurityFilter implements Filter {
|
|||||||
int status = modsecurity.onRequest(modsecurity.getConfFilename(), httpTran, modsecurity.checkModifiedConfig()); //modsecurity reloads only if primary config file is modified
|
int status = modsecurity.onRequest(modsecurity.getConfFilename(), httpTran, modsecurity.checkModifiedConfig()); //modsecurity reloads only if primary config file is modified
|
||||||
|
|
||||||
if (status != ModSecurity.DECLINED) {
|
if (status != ModSecurity.DECLINED) {
|
||||||
|
if (status > 0) {
|
||||||
|
httpTran.getHttpResponse().setStatus(status);
|
||||||
|
httpTran.getHttpResponse().sendError(status);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//process request
|
//process request
|
||||||
fc.doFilter(httpTran.getMsHttpRequest(), httpTran.getMsHttpResponse());
|
fc.doFilter(httpTran.getMsHttpRequest(), httpTran.getMsHttpResponse());
|
||||||
|
|
||||||
|
|
||||||
status = modsecurity.onResponse(httpTran);
|
status = modsecurity.onResponse(httpTran);
|
||||||
|
|
||||||
|
if(status != ModSecurity.OK && status != ModSecurity.DECLINED) {
|
||||||
|
httpTran.getMsHttpResponse().reset();
|
||||||
|
httpTran.getMsHttpResponse().setStatus(status);
|
||||||
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
httpTran.destroy();
|
httpTran.destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,6 +130,24 @@ public class MsHttpServletRequest extends HttpServletRequestWrapper {
|
|||||||
return bodyBytes;
|
return bodyBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBodyBytes(byte[] bytes) throws IOException {
|
||||||
|
String contentType = req.getContentType();
|
||||||
|
bodyBytes = new byte[bytes.length];
|
||||||
|
System.arraycopy(bytes, 0, bodyBytes, 0, bytes.length);
|
||||||
|
|
||||||
|
body = new String(bodyBytes, encoding);
|
||||||
|
if ((contentType != null) && ((contentType.compareTo("application/x-www-form-urlencoded") == 0) || (contentType.compareTo("application/x-form-urlencoded") == 0))) {
|
||||||
|
addUrlEncoded(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContentLength() {
|
||||||
|
if (bodyBytes == null)
|
||||||
|
return req.getContentLength();
|
||||||
|
return bodyBytes.length;
|
||||||
|
}
|
||||||
|
|
||||||
public void readBody(int maxContentLength) throws IOException, ServletException {
|
public void readBody(int maxContentLength) throws IOException, ServletException {
|
||||||
|
|
||||||
String contentType = req.getContentType();
|
String contentType = req.getContentType();
|
||||||
@@ -222,7 +240,6 @@ public class MsHttpServletRequest extends HttpServletRequestWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the given URL-encoded string and adds the parameters to the
|
* Parses the given URL-encoded string and adds the parameters to the
|
||||||
* request parameter list.
|
* request parameter list.
|
||||||
|
|||||||
@@ -202,9 +202,8 @@ public class MsHttpServletResponse extends HttpServletResponseWrapper {
|
|||||||
stream = new ByteArrayInputStream(new String(writer.toCharArray()).getBytes());
|
stream = new ByteArrayInputStream(new String(writer.toCharArray()).getBytes());
|
||||||
} else if (msWriter == null) {
|
} else if (msWriter == null) {
|
||||||
stream = new ByteArrayInputStream(((MsOutputStream) this.getOutputStream()).toByteArray());
|
stream = new ByteArrayInputStream(((MsOutputStream) this.getOutputStream()).toByteArray());
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,6 +286,16 @@ public class MsHttpServletResponse extends HttpServletResponseWrapper {
|
|||||||
return super.isCommitted();
|
return super.isCommitted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBodyBytes(byte[] bytes) throws IOException {
|
||||||
|
if (msOutputStream == null) {
|
||||||
|
msWriter.reset();
|
||||||
|
msWriter.write(new String(bytes));
|
||||||
|
} else if (msWriter == null) {
|
||||||
|
msOutputStream.reset();
|
||||||
|
msOutputStream.write(bytes, 0, bytes.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() throws IllegalStateException {
|
public void reset() throws IllegalStateException {
|
||||||
if (interceptMode != INTERCEPT_ON) {
|
if (interceptMode != INTERCEPT_ON) {
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
<filter-class>org.modsecurity.ModSecurityFilter</filter-class>
|
<filter-class>org.modsecurity.ModSecurityFilter</filter-class>
|
||||||
<init-param>
|
<init-param>
|
||||||
<param-name>conf</param-name>
|
<param-name>conf</param-name>
|
||||||
<param-value>/WEB-INF/modsecurity.conf</param-value>
|
<param-value>c:\inetpub\wwwroot\owasp-crs\modsecurity.conf</param-value>
|
||||||
|
<!--<param-value>/etc/modsecurity/modsecurity.conf</param-value>-->
|
||||||
</init-param>
|
</init-param>
|
||||||
</filter>
|
</filter>
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "org_modsecurity_ModSecurity.h"
|
#include "org_modsecurity_ModSecurity.h"
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#define MODSECURITY_JAVACLASS "org/modsecurity/ModSecurity"
|
#define MODSECURITY_JAVACLASS "org/modsecurity/ModSecurity"
|
||||||
@@ -54,6 +55,8 @@
|
|||||||
|
|
||||||
#define MSHTTPSERVLETREQUEST_READBODY_MET "readBody"
|
#define MSHTTPSERVLETREQUEST_READBODY_MET "readBody"
|
||||||
#define MSHTTPSERVLETREQUEST_READBODY_SIG "(I)V"
|
#define MSHTTPSERVLETREQUEST_READBODY_SIG "(I)V"
|
||||||
|
#define MSHTTPSERVLETREQUEST_SETBODY_MET "setBodyBytes"
|
||||||
|
#define MSHTTPSERVLETREQUEST_SETBODY_SIG "([B)V"
|
||||||
|
|
||||||
#define SERVLETRESPONSE_CONTENTTYPE_MET "getContentType"
|
#define SERVLETRESPONSE_CONTENTTYPE_MET "getContentType"
|
||||||
#define SERVLETRESPONSE_CHARENCODING_MET "getCharacterEncoding"
|
#define SERVLETRESPONSE_CHARENCODING_MET "getCharacterEncoding"
|
||||||
@@ -75,17 +78,22 @@ jmethodID logMethod;
|
|||||||
|
|
||||||
apr_table_t *requests;
|
apr_table_t *requests;
|
||||||
apr_pool_t *requestsPool;
|
apr_pool_t *requestsPool;
|
||||||
|
char *serverHostname;
|
||||||
|
|
||||||
|
#define JAVASERVLET_INSTREAM "MSReqBStr"
|
||||||
#define JAVASERVLET_INSTREAM "ReqBStr"
|
#define JAVASERVLET_OUTSTREAM "MSResBStr"
|
||||||
#define JAVASERVLET_OUTSTREAM "ResBStr"
|
#define JAVASERVLET_TRANSACTION "MSTran"
|
||||||
|
|
||||||
|
|
||||||
void storeJavaServletContext(request_rec *r, const char *key, jobject obj)
|
void storeJavaServletContext(request_rec *r, const char *key, jobject obj)
|
||||||
{
|
{
|
||||||
apr_table_setn(r->notes, key, (const char *)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 getJavaServletContext(request_rec *r, const char *key)
|
||||||
{
|
{
|
||||||
jobject obj = NULL;
|
jobject obj = NULL;
|
||||||
@@ -121,11 +129,6 @@ jobject getJavaServletContext(request_rec *r, const char *key)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//apr_status_t memCleanup(void *mem)
|
|
||||||
//{
|
|
||||||
// free(mem);
|
|
||||||
// return APR_SUCCESS;
|
|
||||||
//}
|
|
||||||
|
|
||||||
apr_sockaddr_t *CopySockAddr(jclass msClass, JNIEnv *env, apr_pool_t *pool, char *addrstr, jstring addrStrJstr)
|
apr_sockaddr_t *CopySockAddr(jclass msClass, JNIEnv *env, apr_pool_t *pool, char *addrstr, jstring addrStrJstr)
|
||||||
{
|
{
|
||||||
@@ -246,6 +249,9 @@ apr_status_t ReadBodyCallback(request_rec *r, char *buf, unsigned int length, un
|
|||||||
*readcnt = count;
|
*readcnt = count;
|
||||||
|
|
||||||
memcpy(buf, bufferPtr, *readcnt);
|
memcpy(buf, bufferPtr, *readcnt);
|
||||||
|
//const char *test = "Foo' or '2' < '1' ;--";
|
||||||
|
//memcpy(buf, test, strlen(test));
|
||||||
|
|
||||||
}
|
}
|
||||||
(env)->ReleaseByteArrayElements(byteArrayBuf, bufferPtr, NULL);
|
(env)->ReleaseByteArrayElements(byteArrayBuf, bufferPtr, NULL);
|
||||||
(env)->DeleteLocalRef(byteArrayBuf);
|
(env)->DeleteLocalRef(byteArrayBuf);
|
||||||
@@ -258,6 +264,38 @@ apr_status_t ReadBodyCallback(request_rec *r, char *buf, unsigned int length, un
|
|||||||
|
|
||||||
apr_status_t WriteBodyCallback(request_rec *r, char *buf, unsigned int length)
|
apr_status_t WriteBodyCallback(request_rec *r, char *buf, unsigned int length)
|
||||||
{
|
{
|
||||||
|
jobject httpTransaction = getJavaServletContext(r, JAVASERVLET_TRANSACTION);
|
||||||
|
JNIEnv *env;
|
||||||
|
|
||||||
|
if(httpTransaction == NULL)
|
||||||
|
{
|
||||||
|
return APR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(jvm)->AttachCurrentThread((void **)&env, NULL))
|
||||||
|
{
|
||||||
|
jclass httpTransactionClass = env->GetObjectClass(httpTransaction);
|
||||||
|
|
||||||
|
jmethodID getHttpRequest = env->GetMethodID(httpTransactionClass, HTTPTRANSACTION_MSHTTPREQUEST_MET, HTTPTRANSACTION_MSHTTPREQUEST_SIG);
|
||||||
|
jobject httpServletRequest = env->CallObjectMethod(httpTransaction, getHttpRequest);
|
||||||
|
|
||||||
|
jclass httpServletRequestClass = env->GetObjectClass(httpServletRequest);
|
||||||
|
jmethodID setBodyBytes = env->GetMethodID(httpServletRequestClass, MSHTTPSERVLETREQUEST_SETBODY_MET, MSHTTPSERVLETREQUEST_SETBODY_SIG);
|
||||||
|
|
||||||
|
jbyte *jbuf = new jbyte[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
jbuf[i] = buf[i];
|
||||||
|
|
||||||
|
jbyteArray byteArrayBuf = (env)->NewByteArray(length);
|
||||||
|
env->SetByteArrayRegion(byteArrayBuf, 0, length, jbuf);
|
||||||
|
|
||||||
|
//on setBodyBytes we copy buf bytes
|
||||||
|
env->CallVoidMethod(httpServletRequest, setBodyBytes, byteArrayBuf);
|
||||||
|
|
||||||
|
//(env)->ReleaseByteArrayElements(byteArrayBuf, jbuf, NULL);
|
||||||
|
|
||||||
|
(jvm)->DetachCurrentThread();
|
||||||
|
}
|
||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,10 +343,43 @@ apr_status_t ReadResponseCallback(request_rec *r, char *buf, unsigned int length
|
|||||||
|
|
||||||
apr_status_t WriteResponseCallback(request_rec *r, char *buf, unsigned int length)
|
apr_status_t WriteResponseCallback(request_rec *r, char *buf, unsigned int length)
|
||||||
{
|
{
|
||||||
|
JNIEnv *env;
|
||||||
|
jobject httpTransaction = getJavaServletContext(r, JAVASERVLET_TRANSACTION);
|
||||||
|
|
||||||
|
if(httpTransaction == NULL)
|
||||||
|
{
|
||||||
|
(jvm)->DetachCurrentThread();
|
||||||
|
return APR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(jvm)->AttachCurrentThread((void **)&env, NULL))
|
||||||
|
{
|
||||||
|
jclass httpTransactionClass = env->GetObjectClass(httpTransaction);
|
||||||
|
|
||||||
|
jmethodID getHttpResponse = env->GetMethodID(httpTransactionClass, HTTPTRANSACTION_MSHTTPRESPONSE_MET, HTTPTRANSACTION_MSHTTPRESPONSE_SIG);
|
||||||
|
jobject httpServletResponse = env->CallObjectMethod(httpTransaction, getHttpResponse);
|
||||||
|
|
||||||
|
jclass httpServletResponseClass = env->GetObjectClass(httpServletResponse);
|
||||||
|
jmethodID setBodyBytes = env->GetMethodID(httpServletResponseClass, MSHTTPSERVLETREQUEST_SETBODY_MET, MSHTTPSERVLETREQUEST_SETBODY_SIG);
|
||||||
|
|
||||||
|
jbyte *jbuf = new jbyte[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
jbuf[i] = buf[i];
|
||||||
|
|
||||||
|
jbyteArray byteArrayBuf = (env)->NewByteArray(length);
|
||||||
|
env->SetByteArrayRegion(byteArrayBuf, 0, length, jbuf);
|
||||||
|
|
||||||
|
//on setBodyBytes we copy buf bytes
|
||||||
|
env->CallVoidMethod(httpServletResponse, setBodyBytes, byteArrayBuf);
|
||||||
|
|
||||||
|
//(env)->ReleaseByteArrayElements(byteArrayBuf, jbuf, NULL);
|
||||||
|
|
||||||
|
(jvm)->DetachCurrentThread();
|
||||||
|
}
|
||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_initialize(JNIEnv *env, jobject obj)
|
JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_initialize(JNIEnv *env, jobject obj, jstring serverName)
|
||||||
{
|
{
|
||||||
(env)->GetJavaVM(&jvm);
|
(env)->GetJavaVM(&jvm);
|
||||||
modSecurityInstance = (env)->NewGlobalRef(obj); //Save the ModSecurity object for further use
|
modSecurityInstance = (env)->NewGlobalRef(obj); //Save the ModSecurity object for further use
|
||||||
@@ -334,6 +405,8 @@ JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_initialize(JNIEnv *env,
|
|||||||
apr_pool_create(&requestsPool, NULL);
|
apr_pool_create(&requestsPool, NULL);
|
||||||
requests = apr_table_make(requestsPool, 10);
|
requests = apr_table_make(requestsPool, 10);
|
||||||
|
|
||||||
|
serverHostname = fromJString(env, serverName, requestsPool);
|
||||||
|
|
||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,6 +477,7 @@ JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_onRequest(JNIEnv *env, j
|
|||||||
modsecProcessConnection(c);
|
modsecProcessConnection(c);
|
||||||
r = modsecNewRequest(c, config);
|
r = modsecNewRequest(c, config);
|
||||||
|
|
||||||
|
r->server->server_hostname = serverHostname;
|
||||||
jclass httpTransactionClass = env->GetObjectClass(httpTransaction);
|
jclass httpTransactionClass = env->GetObjectClass(httpTransaction);
|
||||||
jmethodID getHttpRequest = env->GetMethodID(httpTransactionClass, HTTPTRANSACTION_MSHTTPREQUEST_MET, HTTPTRANSACTION_MSHTTPREQUEST_SIG);
|
jmethodID getHttpRequest = env->GetMethodID(httpTransactionClass, HTTPTRANSACTION_MSHTTPREQUEST_MET, HTTPTRANSACTION_MSHTTPREQUEST_SIG);
|
||||||
|
|
||||||
@@ -424,6 +498,7 @@ JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_onRequest(JNIEnv *env, j
|
|||||||
return DONE;
|
return DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
jmethodID getTransactionID = env->GetMethodID(httpTransactionClass, HTTPTRANSACTION_TRANSACTIONID_MET, STRINGRETURN_SIG);
|
jmethodID getTransactionID = env->GetMethodID(httpTransactionClass, HTTPTRANSACTION_TRANSACTIONID_MET, STRINGRETURN_SIG);
|
||||||
const char *reqID = fromJStringMethod(env, getTransactionID, httpTransaction, r->pool); //fromJString(env, requestID, r->pool); //unique ID of this request
|
const char *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
|
apr_table_setn(requests, reqID, (const char*) r); //store this request for response processing
|
||||||
@@ -433,15 +508,15 @@ JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_onRequest(JNIEnv *env, j
|
|||||||
jobject inputStream = (env)->CallObjectMethod(httpServletRequest, getInputStream); //Request body input stream used in the read body callback
|
jobject inputStream = (env)->CallObjectMethod(httpServletRequest, getInputStream); //Request body input stream used in the read body callback
|
||||||
|
|
||||||
storeJavaServletContext(r, JAVASERVLET_INSTREAM, inputStream);
|
storeJavaServletContext(r, JAVASERVLET_INSTREAM, inputStream);
|
||||||
|
storeJavaServletContext(r, JAVASERVLET_TRANSACTION, httpTransaction);
|
||||||
|
|
||||||
|
|
||||||
jmethodID getServerName = (env)->GetMethodID(servletRequestClass, SERVLETREQUEST_SERVERNAME_MET, STRINGRETURN_SIG);
|
jmethodID getServerName = (env)->GetMethodID(servletRequestClass, SERVLETREQUEST_SERVERNAME_MET, STRINGRETURN_SIG);
|
||||||
r->hostname = fromJStringMethod(env, getServerName, servletRequest, r->pool);
|
r->hostname = fromJStringMethod(env, getServerName, servletRequest, r->pool);
|
||||||
|
|
||||||
jmethodID getServerPort = (env)->GetMethodID(servletRequestClass, SERVLETREQUEST_SERVERPORT_MET, SERVLETREQUEST_SERVERPORT_SIG);
|
jmethodID getServerPort = (env)->GetMethodID(servletRequestClass, SERVLETREQUEST_SERVERPORT_MET, SERVLETREQUEST_SERVERPORT_SIG);
|
||||||
int port = (env)->CallIntMethod(servletRequest, getServerPort); //server port
|
int port = (env)->CallIntMethod(servletRequest, getServerPort); //server port
|
||||||
size_t len = (size_t) ceil(log10((float) port));
|
char *port_str = apr_itoa(r->pool, port);
|
||||||
char *port_str = (char*) apr_palloc(r->pool, len);
|
|
||||||
itoa(port, port_str, 10);
|
|
||||||
|
|
||||||
|
|
||||||
jmethodID getPathInfo = (env)->GetMethodID(httpServletRequestClass, HTTPSERVLETREQUEST_PATHINFO_MET, STRINGRETURN_SIG);
|
jmethodID getPathInfo = (env)->GetMethodID(httpServletRequestClass, HTTPSERVLETREQUEST_PATHINFO_MET, STRINGRETURN_SIG);
|
||||||
@@ -559,9 +634,17 @@ JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_onRequest(JNIEnv *env, j
|
|||||||
#endif
|
#endif
|
||||||
c->remote_host = NULL;
|
c->remote_host = NULL;
|
||||||
|
|
||||||
|
|
||||||
int status = modsecProcessRequest(r);
|
int 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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,11 +682,7 @@ JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_onResponse(JNIEnv *env,
|
|||||||
return DONE;
|
return DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//jclass msOutputStreamClass = env->GetObjectClass(msOutputStream);
|
storeJavaServletContext(r, JAVASERVLET_TRANSACTION, httpTransaction);
|
||||||
|
|
||||||
//jmethodID getByteArrayStream = env->GetMethodID(msOutputStreamClass, MSOUTPUTSTREAM_INPUTSTREAM_MET, MSOUTPUTSTREAM_INPUTSTREAM_SIG);
|
|
||||||
//jobject responseStream = env->CallObjectMethod(msOutputStream, getByteArrayStream);
|
|
||||||
|
|
||||||
storeJavaServletContext(r, JAVASERVLET_OUTSTREAM, responseStream);
|
storeJavaServletContext(r, JAVASERVLET_OUTSTREAM, responseStream);
|
||||||
|
|
||||||
|
|
||||||
@@ -629,16 +708,9 @@ JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_onResponse(JNIEnv *env,
|
|||||||
|
|
||||||
int status = modsecProcessResponse(r);
|
int status = modsecProcessResponse(r);
|
||||||
|
|
||||||
|
removeJavaServletContext(r, JAVASERVLET_OUTSTREAM);
|
||||||
|
removeJavaServletContext(r, JAVASERVLET_TRANSACTION);
|
||||||
modsecFinishRequest(r);
|
modsecFinishRequest(r);
|
||||||
|
|
||||||
// the logic here is temporary, needs clarification
|
|
||||||
if(status != 0 && status != -1)
|
|
||||||
{
|
|
||||||
//reset the stream, clear the response
|
|
||||||
jmethodID reset = (env)->GetMethodID(httpServletResponseClass, MSSERVLETRESPONSE_RESET_MET, MSSERVLETRESPONSE_RESET_SIG);
|
|
||||||
env->CallVoidMethod(httpServletResponse, reset);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ extern "C" {
|
|||||||
/*
|
/*
|
||||||
* Class: org_modsecurity_ModSecurity
|
* Class: org_modsecurity_ModSecurity
|
||||||
* Method: initialize
|
* Method: initialize
|
||||||
* Signature: ()I
|
* Signature: (Ljava/lang/String;)I
|
||||||
*/
|
*/
|
||||||
JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_initialize
|
JNIEXPORT jint JNICALL Java_org_modsecurity_ModSecurity_initialize
|
||||||
(JNIEnv *, jobject);
|
(JNIEnv *, jobject, jstring);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_modsecurity_ModSecurity
|
* Class: org_modsecurity_ModSecurity
|
||||||
|
|||||||
Reference in New Issue
Block a user