# das-sdap-plugin-demo **Repository Path**: blackg/das-sdap-plugin-demo ## Basic Information - **Project Name**: das-sdap-plugin-demo - **Description**: DAS-SDAP 平台插件 demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-04-02 - **Last Updated**: 2024-04-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # **DAS-SDAP** 插件开发 SDK 指南 ## SDK **介绍** 在实际给客户交付方案的过程中,经常开发针对性的代码用来调用客户已有的扫描器完成相关的扫描任务。客户具有开发能里的情况下,可根据 DAS-SDAP 提供的插件开发 SDK自行开发插件 ## 依赖引用 + 安装 sdk 依赖到本地仓库,替换**path/to/dipper-plugin-sdk.jar**为自己的 sdk 路径 ```shell mvn install:install-file -Dfile=path/to/dipper-plugin-sdk.jar -DgroupId=com.dbapp -DartifactId=dipper-plugin-sdk -Dversion=3.8 -Dpackaging=jar -Dscope=provided ``` + pom 中引用依赖,scope设置为provided,不将其打包到最终的构建产物 ```xml com.dbapp dipper-plugin-sdk 3.8 provided ``` + 添加 **maven-shade-plugin** 打包插件,将所有第三方依赖都打入 jar 中 ```xml org.apache.maven.plugins maven-shade-plugin 3.2.4 package shade ``` ## **插件****初始化****类** ​ ● 包中添加插件初始化类,用于平台识别插件 ``` package com.dbapp.dassdap.plugin.demo; import org.pf4j.PluginWrapper; import org.pf4j.spring.SpringPlugin; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Plugin extends SpringPlugin { public Plugin(PluginWrapper wrapper) { super(wrapper); } @Override public void stop() { super.stop(); } @Override protected ApplicationContext createApplicationContext() { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.setClassLoader(getWrapper().getPluginClassLoader()); applicationContext.refresh(); return applicationContext; } } ``` ## 插件描述配置 + 项目**resource** 下添加 **plugin.properties** 配置,用于配置插件基础信息 ```properties plugin.id=das-sdap-plugin-demo plugin.key=plugin-demo plugin.class=com.dbapp.dassdap.plugin.demo.Plugin plugin.version=1.0 plugin.provider=www.dbappsecurity.com.cn plugin.description=我是插件描述 plugin.capability=SOURCE_CODE ``` + **plugin.capability**:插件能力,多种能力以英文逗号','隔开 + HOST:主机安全检测 + SOURCE_CODE:静态源代码安全检测 + WEB:动态安全检测 + APP:移动应用安全检测 + **plugin.class**:填写插件初始化类的类路径 + ## 插件任务实现 + 创建实现类,实现 **PluginTask** 接口 ```java package com.dbapp.dassdap.plugin.demo.main; import cn.hutool.core.bean.BeanUtil; import com.dbapp.dassdap.plugin.demo.Config; import com.dbapp.dipper.plugin.sdk.bean.to.TaskCreateModel; import com.dbapp.dipper.plugin.sdk.bean.to.VulDataModel; import com.dbapp.dipper.plugin.sdk.common.enums.TaskStatus; import com.dbapp.dipper.plugin.sdk.interfaces.PluginTask; import com.dbapp.dipper.util.Result; import org.pf4j.Extension; import java.io.File; import java.io.InputStream; import java.util.List; import java.util.Map; @Extension public class PluginTaskImpl implements PluginTask { private Config config; /** * 创建任务 * * @param taskCreateModel 平台新建任务时相关的参数 * @param file 平台新建任务时上传的文件 */ @Override public Result createTask(TaskCreateModel taskCreateModel, File file) throws Exception { return null; } /** * 运行任务,如果任务以默认启动,可以不写。 * @param o 创建任务方法返回的参数 * @return * @throws Exception */ @Override public Result runTask(Object o) throws Exception { return null; } /** * 暂停任务,页面点击暂停时调用 * @param o 创建任务的返回参数 * @param o1 启动任务的返回参数 * @return * @throws Exception */ @Override public Result stop(Object o, Object o1) throws Exception { return null; } /** * 任务进度,系统每5秒调用一次,请返回当前任务的最新状态 * @param o 创建任务的返回参数 * @param o1 启动任务的返回参数 * @return * @throws Exception */ @Override public Result taskProgress(Object o, Object o1) throws Exception { return null; } /** * 获取扫描报告,任务结束时系统会调用,请返回 zip 格式报告的 stream 流 * @param o 创建任务的返回参数 * @param o1 启动任务的返回参数 * @return * @throws Exception */ @Override public Result getReport(Object o, Object o1) throws Exception { return null; } /** * 任务报告解析,报告解析任务时会调用该方法,根据传入的 file 报告,解析为漏洞返回 * @param file 报告文件 * @param o 创建任务的返回参数 * @param o1 启动任务的返回参数 * @return * @throws Exception */ @Override public Result> analysisReport(File file, Object o, Object o1) throws Exception { return null; } /** * 获取任务漏洞,任务结束时,系统会调用该方法获取任务全部漏洞数据 * @param o 创建任务的返回参数 * @param o1 启动任务的返回参数 * @return * @throws Exception */ @Override public Result> getVuls(Object o, Object o1) throws Exception { return null; } /** * 插件配置模型,返回当前插件的配置参数模板,用于插件编辑时的填写 * @return * @throws Exception */ @Override public Result> getConfigurtionModel() { Map beanToMap = BeanUtil.beanToMap(new Config()); return Result.wrapSuccessfulResult(beanToMap); } /** * 插件初始化配置,任务调度时,平台会将扩展参数传入插件,插件需要识别 map 格式的参数,转换为自己的配置类并初始化 * @param map * @return * @throws Exception */ @Override public Result initConfigurtion(Map map) { this.config = BeanUtil.mapToBean(map, Config.class, false); return Result.wrapSuccessfulResult(true); } } ``` ## **插件配置表单实现** + 任务实现类中添加实现 **PluginForm** 接口,也可单独创建类实现 ```java @Extension public class PluginTaskImpl implements PluginTask, PluginForm { .... /** * 返回插件的配置表单 * @return */ @Override public PluginFormModel getPluginForm() { InputText url = new InputText("url", "http://host:port/", true, "url", "请填写服务端地址", "服务端路径地址"); InputText username = new InputText("username", "admin", true, "用户名", "请填写用户名", "用户名"); InputPassword password = new InputPassword("password", "admin", true, "密码", "请填写密码", "密码"); List components = Arrays.asList(url, username, password); return new PluginFormModel(components); } } ``` ## 插件连通性检测实现 + 实现 **PluginConnectivity** 接口,返回插件配置的校验信息 ```java @Extension public class PluginTaskImpl implements PluginTask, PluginForm, PluginConnectivity { .... } ``` ## 插件Icon图标实现 + 实现 PluginIcon 接口后,该接口方法可不实现,平台将默认获取 resource 下的 icon.png,作为插件图标展示 ```java @Extension public class PluginTaskImpl implements PluginTask, PluginForm, PluginIcon { .... @Override public List test(Map map) { initConfigurtion(map); List result = new ArrayList<>(); { //url校验 Connectivity connectivity = ConnectivityUtile.checkUrl(config.getUrl()); connectivity.setTitle("url"); result.add(connectivity); } { //账号密码校验 Connectivity connectivity = Connectivity.builder().title("token") .title("username or password") .state(ConnectivityState.SUCCESS) .build(); if (!"admin".equals(config.getUsername()) && !"admin".equals(config.getPassword())) { connectivity.setState(ConnectivityState.FAILURE); connectivity.setMessage("账号或密码错误"); } result.add(connectivity); } return result; } } ``` ## 插件签名 ```shell jarsigner -verbose -keystore pluginKeyStore -signedjar das-sdap-plugin-demo-1.0.jar target/das-sdap-plugin-demo-1.0.jar james ``` ## **参考项目** https://gitee.com/blackg/das-sdap-plugin-demo.git