package core import ( "fmt" "github.com/shadow1ng/fscan/common" "github.com/shadow1ng/fscan/plugins/services" "strings" ) // PluginFilterType 插件过滤类型 type PluginFilterType int const ( FilterNone PluginFilterType = iota // 不过滤 FilterLocal // 仅本地插件 FilterService // 仅服务插件(排除本地) FilterWeb // 仅Web插件 ) // BaseScanStrategy 扫描策略基础类 type BaseScanStrategy struct { strategyName string filterType PluginFilterType } // NewBaseScanStrategy 创建基础扫描策略 func NewBaseScanStrategy(name string, filterType PluginFilterType) *BaseScanStrategy { return &BaseScanStrategy{ strategyName: name, filterType: filterType, } } // GetPlugins 获取插件列表(简化版) func (b *BaseScanStrategy) GetPlugins() ([]string, bool) { // 如果指定了特定插件且不是"all" if common.ScanMode != "" && common.ScanMode != "all" { requestedPlugins := parsePluginList(common.ScanMode) if len(requestedPlugins) == 0 { requestedPlugins = []string{common.ScanMode} } // 验证插件是否存在 var validPlugins []string for _, name := range requestedPlugins { if services.GetPlugin(name) != nil { validPlugins = append(validPlugins, name) } } return validPlugins, true } // 未指定或使用"all":获取所有插件 return services.GetAllPlugins(), false } // IsPluginApplicable 判断插件是否适用(传统接口兼容) func (b *BaseScanStrategy) IsPluginApplicable(plugin common.ScanPlugin, targetPort int, isCustomMode bool) bool { // 自定义模式下运行所有明确指定的插件 if isCustomMode { return true } // 检查插件类型过滤 switch b.filterType { case FilterLocal: return plugin.HasType(common.PluginTypeLocal) case FilterService: // 服务扫描排除本地插件,允许服务和Web插件 return !plugin.HasType(common.PluginTypeLocal) case FilterWeb: return plugin.HasType(common.PluginTypeWeb) default: return true } } // IsPluginApplicableByName 根据插件名称判断是否适用(新接口) func (b *BaseScanStrategy) IsPluginApplicableByName(pluginName string, targetHost string, targetPort int, isCustomMode bool) bool { // 自定义模式下运行所有明确指定的插件 if isCustomMode { return true } // 获取插件实例 plugin := services.GetPlugin(pluginName) if plugin == nil { return false } // 检查端口匹配(如果指定了端口) if targetPort > 0 { pluginPorts := plugin.GetPorts() if len(pluginPorts) > 0 { found := false for _, port := range pluginPorts { if port == targetPort { found = true break } } if !found { return false } } } return true } // LogPluginInfo 输出插件信息(简化版) func (b *BaseScanStrategy) LogPluginInfo() { allPlugins, isCustomMode := b.GetPlugins() var prefix string switch b.filterType { case FilterLocal: prefix = "本地插件" case FilterService: prefix = "服务插件" case FilterWeb: prefix = "Web插件" default: prefix = "插件" } if len(allPlugins) > 0 { if isCustomMode { common.LogBase(fmt.Sprintf("%s: 自定义指定 (%s)", prefix, strings.Join(allPlugins, ", "))) } else { common.LogBase(fmt.Sprintf("%s: %s", prefix, strings.Join(allPlugins, ", "))) } } else { common.LogBase(fmt.Sprintf("%s: 无可用插件", prefix)) } } // ValidateConfiguration 验证扫描配置 func (b *BaseScanStrategy) ValidateConfiguration() error { return nil } // LogScanStart 输出扫描开始信息 func (b *BaseScanStrategy) LogScanStart() { switch b.filterType { case FilterLocal: common.LogBase("开始本地扫描") case FilterService: common.LogBase("开始服务扫描") case FilterWeb: common.LogBase("开始Web扫描") default: common.LogBase("开始扫描") } } // parsePluginList 解析插件列表字符串 func parsePluginList(pluginStr string) []string { if pluginStr == "" { return []string{} } // 支持逗号分隔的插件列表 plugins := strings.Split(pluginStr, ",") var result []string for _, plugin := range plugins { plugin = strings.TrimSpace(plugin) if plugin != "" { result = append(result, plugin) } } return result }