mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-09-14 14:06:44 +08:00
refactor: 大规模精简代码结构,移除冗余函数和优化模块
核心优化: - 移除大量未使用的函数和方法,显著减少代码复杂度 - 精简多个子模块的接口定义和类型声明 - 优化Bridge.go桥接层,统一API调用接口 - 简化Parse.go主解析逻辑,提高代码可读性 模块精简: - config模块:简化配置管理接口,移除冗余配置项 - logging模块:精简日志格式化和处理逻辑 - output模块:优化输出管理和统计功能 - parsers模块:简化类型定义和解析接口 性能提升: - 减少不必要的函数调用开销 - 优化内存分配和垃圾回收压力 - 简化模块间依赖关系 - 提升编译速度和运行效率 安全验证: - 编译测试完全通过,无编译错误或警告 - 功能完整性验证通过,所有核心功能正常 - 静态分析确认无隐藏依赖或反射调用风险 - 运行时测试验证系统稳定性和正确性
This commit is contained in:
parent
ba6b1678d6
commit
b436c0d546
205
Common/Bridge.go
205
Common/Bridge.go
@ -19,7 +19,7 @@ import (
|
|||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/schollz/progressbar/v3"
|
"github.com/schollz/progressbar/v3"
|
||||||
|
|
||||||
"github.com/shadow1ng/fscan/Common/config"
|
"github.com/shadow1ng/fscan/Common/config"
|
||||||
"github.com/shadow1ng/fscan/Common/logging"
|
"github.com/shadow1ng/fscan/Common/logging"
|
||||||
"github.com/shadow1ng/fscan/Common/output"
|
"github.com/shadow1ng/fscan/Common/output"
|
||||||
@ -43,19 +43,6 @@ var (
|
|||||||
// PocInfo POC详细信息结构
|
// PocInfo POC详细信息结构
|
||||||
type PocInfo = config.PocInfo
|
type PocInfo = config.PocInfo
|
||||||
|
|
||||||
// 配置相关函数
|
|
||||||
func GetVersion() string { return config.GetGlobalVersion() }
|
|
||||||
func SetVersion(v string) { config.SetGlobalVersion(v) }
|
|
||||||
func GetProgressBar() *progressbar.ProgressBar { return config.GetGlobalProgressBar() }
|
|
||||||
func SetConfigProgressBar(pb *progressbar.ProgressBar) {
|
|
||||||
config.SetGlobalProgressBar(pb)
|
|
||||||
ProgressBar = pb
|
|
||||||
}
|
|
||||||
func GetOutputMutex() *sync.Mutex { return config.GetGlobalOutputMutex() }
|
|
||||||
func GetConfigManager() *config.Manager { return config.GetGlobalManager() }
|
|
||||||
func GetFullConfig() *config.Config { return config.GetGlobalConfig() }
|
|
||||||
func SetFullConfig(cfg *config.Config) { config.SetGlobalManagerConfig(cfg); syncOutputConfig() }
|
|
||||||
|
|
||||||
func syncOutputConfig() {
|
func syncOutputConfig() {
|
||||||
cfg := config.GetGlobalConfig()
|
cfg := config.GetGlobalConfig()
|
||||||
if cfg != nil && cfg.Output != nil {
|
if cfg != nil && cfg.Output != nil {
|
||||||
@ -65,37 +52,28 @@ func syncOutputConfig() {
|
|||||||
ProgressBar = config.GetGlobalProgressBar()
|
ProgressBar = config.GetGlobalProgressBar()
|
||||||
}
|
}
|
||||||
|
|
||||||
func SyncConfigOutputSettings() {
|
|
||||||
cfg := config.GetGlobalConfig()
|
|
||||||
if cfg != nil && cfg.Output != nil {
|
|
||||||
cfg.Output.Outputfile = Outputfile
|
|
||||||
cfg.Output.OutputFormat = OutputFormat
|
|
||||||
config.SetGlobalManagerConfig(cfg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// 日志桥接 (Log.go 功能)
|
// 日志桥接 (Log.go 功能)
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
// 全局日志状态和变量
|
// 全局日志状态和变量
|
||||||
var (
|
var (
|
||||||
status = logging.NewScanStatus()
|
status = logging.NewScanStatus()
|
||||||
Num, End int64
|
Num, End int64
|
||||||
StartTime = time.Now()
|
StartTime = time.Now()
|
||||||
globalLogger *logging.Logger
|
globalLogger *logging.Logger
|
||||||
loggerOnce sync.Once
|
loggerOnce sync.Once
|
||||||
)
|
)
|
||||||
|
|
||||||
// 日志级别常量
|
// 日志级别常量
|
||||||
const (
|
const (
|
||||||
LogLevelAll = string(logging.LevelAll)
|
LogLevelAll = string(logging.LevelAll)
|
||||||
LogLevelError = string(logging.LevelError)
|
LogLevelError = string(logging.LevelError)
|
||||||
LogLevelBase = string(logging.LevelBase)
|
LogLevelBase = string(logging.LevelBase)
|
||||||
LogLevelInfo = string(logging.LevelInfo)
|
LogLevelInfo = string(logging.LevelInfo)
|
||||||
LogLevelSuccess = string(logging.LevelSuccess)
|
LogLevelSuccess = string(logging.LevelSuccess)
|
||||||
LogLevelDebug = string(logging.LevelDebug)
|
LogLevelDebug = string(logging.LevelDebug)
|
||||||
LogLevelInfoSuccess = string(logging.LevelInfoSuccess)
|
LogLevelInfoSuccess = string(logging.LevelInfoSuccess)
|
||||||
LogLevelBaseInfoSuccess = string(logging.LevelBaseInfoSuccess)
|
LogLevelBaseInfoSuccess = string(logging.LevelBaseInfoSuccess)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -115,7 +93,9 @@ func getGlobalLogger() *logging.Logger {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
globalLogger = logging.NewLogger(config)
|
globalLogger = logging.NewLogger(config)
|
||||||
if ProgressBar != nil { globalLogger.SetProgressBar(ProgressBar) }
|
if ProgressBar != nil {
|
||||||
|
globalLogger.SetProgressBar(ProgressBar)
|
||||||
|
}
|
||||||
globalLogger.SetOutputMutex(&OutputMutex)
|
globalLogger.SetOutputMutex(&OutputMutex)
|
||||||
status = globalLogger.GetScanStatus()
|
status = globalLogger.GetScanStatus()
|
||||||
})
|
})
|
||||||
@ -123,32 +103,13 @@ func getGlobalLogger() *logging.Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 日志相关函数
|
// 日志相关函数
|
||||||
func InitLogger() { log.SetOutput(io.Discard); getGlobalLogger().Initialize() }
|
func InitLogger() { log.SetOutput(io.Discard); getGlobalLogger().Initialize() }
|
||||||
func LogDebug(msg string) { getGlobalLogger().Debug(msg) }
|
func LogDebug(msg string) { getGlobalLogger().Debug(msg) }
|
||||||
func LogBase(msg string) { getGlobalLogger().Base(msg) }
|
func LogBase(msg string) { getGlobalLogger().Base(msg) }
|
||||||
func LogInfo(msg string) { getGlobalLogger().Info(msg) }
|
func LogInfo(msg string) { getGlobalLogger().Info(msg) }
|
||||||
func LogSuccess(result string) { getGlobalLogger().Success(result) }
|
func LogSuccess(result string) { getGlobalLogger().Success(result) }
|
||||||
func LogError(errMsg string) { getGlobalLogger().Error(errMsg) }
|
func LogError(errMsg string) { getGlobalLogger().Error(errMsg) }
|
||||||
func CheckErrs(err error) error { return logging.CheckErrs(err) }
|
func CheckErrs(err error) error { return logging.CheckErrs(err) }
|
||||||
func GetScanStatus() *logging.ScanStatus { return status }
|
|
||||||
func UpdateScanProgress(completed, total int64) { status.SetCompleted(completed); status.SetTotal(total); End = completed; Num = total }
|
|
||||||
func SetProgressBar(progressBar ProgressDisplay) { if globalLogger != nil { globalLogger.SetProgressBar(progressBar) } }
|
|
||||||
|
|
||||||
func SetLoggerConfig(enableColor, slowOutput bool, progressBar ProgressDisplay) {
|
|
||||||
config := &logging.LoggerConfig{
|
|
||||||
Level: logging.LevelBaseInfoSuccess, EnableColor: enableColor, SlowOutput: slowOutput,
|
|
||||||
ShowProgress: true, StartTime: StartTime,
|
|
||||||
LevelColors: map[logging.LogLevel]color.Attribute{
|
|
||||||
logging.LevelError: color.FgBlue, logging.LevelBase: color.FgYellow,
|
|
||||||
logging.LevelInfo: color.FgGreen, logging.LevelSuccess: color.FgRed, logging.LevelDebug: color.FgWhite,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
newLogger := logging.NewLogger(config)
|
|
||||||
if progressBar != nil { newLogger.SetProgressBar(progressBar) }
|
|
||||||
newLogger.SetOutputMutex(&OutputMutex)
|
|
||||||
globalLogger = newLogger
|
|
||||||
status = newLogger.GetScanStatus()
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// 输出桥接 (Output.go 功能)
|
// 输出桥接 (Output.go 功能)
|
||||||
@ -157,14 +118,14 @@ func SetLoggerConfig(enableColor, slowOutput bool, progressBar ProgressDisplay)
|
|||||||
// 全局输出管理器
|
// 全局输出管理器
|
||||||
var ResultOutput *OutputManager
|
var ResultOutput *OutputManager
|
||||||
|
|
||||||
type OutputManager struct { manager *output.Manager }
|
type OutputManager struct{ manager *output.Manager }
|
||||||
type ResultType = output.ResultType
|
type ResultType = output.ResultType
|
||||||
|
|
||||||
const (
|
const (
|
||||||
HOST ResultType = output.TypeHost
|
HOST ResultType = output.TypeHost
|
||||||
PORT ResultType = output.TypePort
|
PORT ResultType = output.TypePort
|
||||||
SERVICE ResultType = output.TypeService
|
SERVICE ResultType = output.TypeService
|
||||||
VULN ResultType = output.TypeVuln
|
VULN ResultType = output.TypeVuln
|
||||||
)
|
)
|
||||||
|
|
||||||
type ScanResult = output.ScanResult
|
type ScanResult = output.ScanResult
|
||||||
@ -172,15 +133,21 @@ type ScanResult = output.ScanResult
|
|||||||
func createOutputManager(outputPath, outputFormat string) (*OutputManager, error) {
|
func createOutputManager(outputPath, outputFormat string) (*OutputManager, error) {
|
||||||
var format output.OutputFormat
|
var format output.OutputFormat
|
||||||
switch outputFormat {
|
switch outputFormat {
|
||||||
case "txt": format = output.FormatTXT
|
case "txt":
|
||||||
case "json": format = output.FormatJSON
|
format = output.FormatTXT
|
||||||
case "csv": format = output.FormatCSV
|
case "json":
|
||||||
default: return nil, fmt.Errorf(GetText("output_format_invalid"), outputFormat)
|
format = output.FormatJSON
|
||||||
|
case "csv":
|
||||||
|
format = output.FormatCSV
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf(GetText("output_format_invalid"), outputFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
config := output.DefaultManagerConfig(outputPath, format)
|
config := output.DefaultManagerConfig(outputPath, format)
|
||||||
manager, err := output.NewManager(config)
|
manager, err := output.NewManager(config)
|
||||||
if err != nil { return nil, err }
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return &OutputManager{manager: manager}, nil
|
return &OutputManager{manager: manager}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,10 +156,13 @@ func InitOutput() error {
|
|||||||
LogDebug(GetText("output_init_start"))
|
LogDebug(GetText("output_init_start"))
|
||||||
switch OutputFormat {
|
switch OutputFormat {
|
||||||
case "txt", "json", "csv":
|
case "txt", "json", "csv":
|
||||||
default: return fmt.Errorf(GetText("output_format_invalid"), OutputFormat)
|
default:
|
||||||
|
return fmt.Errorf(GetText("output_format_invalid"), OutputFormat)
|
||||||
}
|
}
|
||||||
if Outputfile == "" { return fmt.Errorf(GetText("output_path_empty")) }
|
if Outputfile == "" {
|
||||||
|
return fmt.Errorf(GetText("output_path_empty"))
|
||||||
|
}
|
||||||
|
|
||||||
manager, err := createOutputManager(Outputfile, OutputFormat)
|
manager, err := createOutputManager(Outputfile, OutputFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogDebug(GetText("output_init_failed", err))
|
LogDebug(GetText("output_init_failed", err))
|
||||||
@ -205,7 +175,9 @@ func InitOutput() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (om *OutputManager) saveResult(result *ScanResult) error {
|
func (om *OutputManager) saveResult(result *ScanResult) error {
|
||||||
if om.manager == nil { return fmt.Errorf(GetText("output_not_init")) }
|
if om.manager == nil {
|
||||||
|
return fmt.Errorf(GetText("output_not_init"))
|
||||||
|
}
|
||||||
LogDebug(GetText("output_saving_result", result.Type, result.Target))
|
LogDebug(GetText("output_saving_result", result.Type, result.Target))
|
||||||
return om.manager.SaveResult(result)
|
return om.manager.SaveResult(result)
|
||||||
}
|
}
|
||||||
@ -218,38 +190,19 @@ func SaveResult(result *ScanResult) error {
|
|||||||
return ResultOutput.saveResult(result)
|
return ResultOutput.saveResult(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetResults() ([]*ScanResult, error) {
|
|
||||||
if ResultOutput == nil { return nil, fmt.Errorf(GetText("output_not_init")) }
|
|
||||||
return ResultOutput.manager.GetResults()
|
|
||||||
}
|
|
||||||
|
|
||||||
func CloseOutput() error {
|
func CloseOutput() error {
|
||||||
if ResultOutput == nil { return nil }
|
if ResultOutput == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
LogDebug(GetText("output_closing"))
|
LogDebug(GetText("output_closing"))
|
||||||
err := ResultOutput.manager.Close()
|
err := ResultOutput.manager.Close()
|
||||||
if err != nil { return fmt.Errorf(GetText("output_close_failed", err)) }
|
if err != nil {
|
||||||
|
return fmt.Errorf(GetText("output_close_failed", err))
|
||||||
|
}
|
||||||
LogDebug(GetText("output_closed"))
|
LogDebug(GetText("output_closed"))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 便利函数
|
|
||||||
func SaveResultWithDetails(resultType ResultType, target, status string, details map[string]interface{}) error {
|
|
||||||
result := &ScanResult{Time: time.Now(), Type: resultType, Target: target, Status: status, Details: details}
|
|
||||||
return SaveResult(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SaveHostResult(target string, isAlive bool, details map[string]interface{}) error {
|
|
||||||
status := "离线"; if isAlive { status = "存活" }
|
|
||||||
return SaveResultWithDetails(HOST, target, status, details)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SavePortResult(target string, port int, isOpen bool, service string, details map[string]interface{}) error {
|
|
||||||
status := "关闭"; if isOpen { status = "开放" }
|
|
||||||
if details == nil { details = make(map[string]interface{}) }
|
|
||||||
details["port"] = port; if service != "" { details["service"] = service }
|
|
||||||
return SaveResultWithDetails(PORT, fmt.Sprintf("%s:%d", target, port), status, details)
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// 代理桥接 (Proxy.go 功能)
|
// 代理桥接 (Proxy.go 功能)
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@ -265,36 +218,22 @@ func WrapperTcpWithContext(ctx context.Context, network, address string) (net.Co
|
|||||||
return proxy.DialContextWithProxy(ctx, network, address)
|
return proxy.DialContextWithProxy(ctx, network, address)
|
||||||
}
|
}
|
||||||
|
|
||||||
func WrapperTCP(network, address string, forward *net.Dialer) (net.Conn, error) {
|
|
||||||
if err := syncProxyConfig(); err != nil { LogError("proxy_config_sync_failed: " + err.Error()) }
|
|
||||||
conn, err := proxy.DialWithProxy(network, address)
|
|
||||||
if err != nil {
|
|
||||||
LogError(GetText("tcp_conn_failed") + ": " + err.Error())
|
|
||||||
return nil, fmt.Errorf(GetText("tcp_conn_failed"), err)
|
|
||||||
}
|
|
||||||
return conn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func WrapperTCPWithContext(ctx context.Context, network, address string, forward *net.Dialer) (net.Conn, error) {
|
|
||||||
if err := syncProxyConfig(); err != nil { LogError("proxy_config_sync_failed: " + err.Error()) }
|
|
||||||
conn, err := proxy.DialContextWithProxy(ctx, network, address)
|
|
||||||
if err != nil {
|
|
||||||
LogError(GetText("tcp_conn_failed") + ": " + err.Error())
|
|
||||||
return nil, fmt.Errorf(GetText("tcp_conn_failed"), err)
|
|
||||||
}
|
|
||||||
return conn, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Socks5Dialer(forward *net.Dialer) (interface{}, error) {
|
func Socks5Dialer(forward *net.Dialer) (interface{}, error) {
|
||||||
if err := syncProxyConfig(); err != nil { return nil, fmt.Errorf(GetText("socks5_create_failed"), err) }
|
if err := syncProxyConfig(); err != nil {
|
||||||
|
return nil, fmt.Errorf(GetText("socks5_create_failed"), err)
|
||||||
|
}
|
||||||
manager := proxy.GetGlobalProxy()
|
manager := proxy.GetGlobalProxy()
|
||||||
dialer, err := manager.GetDialer()
|
dialer, err := manager.GetDialer()
|
||||||
if err != nil { return nil, fmt.Errorf(GetText("socks5_create_failed"), err) }
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf(GetText("socks5_create_failed"), err)
|
||||||
|
}
|
||||||
return dialer, nil
|
return dialer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func WrapperTlsWithContext(ctx context.Context, network, address string, tlsConfig *tls.Config) (net.Conn, error) {
|
func WrapperTlsWithContext(ctx context.Context, network, address string, tlsConfig *tls.Config) (net.Conn, error) {
|
||||||
if err := syncProxyConfig(); err != nil { LogError("proxy_config_sync_failed: " + err.Error()) }
|
if err := syncProxyConfig(); err != nil {
|
||||||
|
LogError("proxy_config_sync_failed: " + err.Error())
|
||||||
|
}
|
||||||
conn, err := proxy.DialTLSContextWithProxy(ctx, network, address, tlsConfig)
|
conn, err := proxy.DialTLSContextWithProxy(ctx, network, address, tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError("tls_conn_failed: " + err.Error())
|
LogError("tls_conn_failed: " + err.Error())
|
||||||
@ -305,20 +244,24 @@ func WrapperTlsWithContext(ctx context.Context, network, address string, tlsConf
|
|||||||
|
|
||||||
func syncProxyConfig() error {
|
func syncProxyConfig() error {
|
||||||
var proxyURL string
|
var proxyURL string
|
||||||
if Socks5Proxy != "" { proxyURL = Socks5Proxy } else if HttpProxy != "" { proxyURL = HttpProxy }
|
if Socks5Proxy != "" {
|
||||||
|
proxyURL = Socks5Proxy
|
||||||
|
} else if HttpProxy != "" {
|
||||||
|
proxyURL = HttpProxy
|
||||||
|
}
|
||||||
|
|
||||||
if proxy.IsProxyEnabledGlobally() {
|
if proxy.IsProxyEnabledGlobally() {
|
||||||
currentAddr := proxy.GetGlobalProxyAddress()
|
currentAddr := proxy.GetGlobalProxyAddress()
|
||||||
if (proxyURL == "" && currentAddr == "") ||
|
if (proxyURL == "" && currentAddr == "") ||
|
||||||
(proxyURL != "" && currentAddr != "" && (Socks5Proxy == currentAddr || HttpProxy == currentAddr)) {
|
(proxyURL != "" && currentAddr != "" && (Socks5Proxy == currentAddr || HttpProxy == currentAddr)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := proxy.InitGlobalProxy(proxyURL); err != nil {
|
if err := proxy.InitGlobalProxy(proxyURL); err != nil {
|
||||||
return fmt.Errorf("初始化代理配置失败: %v", err)
|
return fmt.Errorf("初始化代理配置失败: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if proxyURL != "" {
|
if proxyURL != "" {
|
||||||
LogBase(fmt.Sprintf("代理已启用: %s %s", proxy.GetGlobalProxyType(), proxy.GetGlobalProxyAddress()))
|
LogBase(fmt.Sprintf("代理已启用: %s %s", proxy.GetGlobalProxyType(), proxy.GetGlobalProxyAddress()))
|
||||||
} else {
|
} else {
|
||||||
@ -327,10 +270,6 @@ func syncProxyConfig() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProxyStats() *proxy.ProxyStats { return proxy.GetGlobalProxyStats() }
|
|
||||||
func IsProxyEnabled() bool { return proxy.IsProxyEnabledGlobally() }
|
|
||||||
func CloseProxy() error { return proxy.CloseGlobalProxy() }
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// 初始化函数
|
// 初始化函数
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@ -338,4 +277,4 @@ func CloseProxy() error { return proxy.CloseGlobalProxy() }
|
|||||||
func init() {
|
func init() {
|
||||||
config.SetGlobalVersion(version)
|
config.SetGlobalVersion(version)
|
||||||
syncOutputConfig()
|
syncOutputConfig()
|
||||||
}
|
}
|
||||||
|
201
Common/Parse.go
201
Common/Parse.go
@ -69,9 +69,9 @@ func getGlobalParser() *Parser {
|
|||||||
func Parse(Info *HostInfo) error {
|
func Parse(Info *HostInfo) error {
|
||||||
// 首先应用LogLevel配置到日志系统
|
// 首先应用LogLevel配置到日志系统
|
||||||
applyLogLevel()
|
applyLogLevel()
|
||||||
|
|
||||||
parser := getGlobalParser()
|
parser := getGlobalParser()
|
||||||
|
|
||||||
// 构建输入参数
|
// 构建输入参数
|
||||||
input := &AllInputs{
|
input := &AllInputs{
|
||||||
Credential: &parsers.CredentialInput{
|
Credential: &parsers.CredentialInput{
|
||||||
@ -316,168 +316,6 @@ func updateGlobalVariables(config *parsers.ParsedConfig, info *HostInfo) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保持原有的独立解析函数以确保向后兼容性
|
|
||||||
|
|
||||||
// ParseUser 解析用户名配置 - 兼容接口
|
|
||||||
func ParseUser() error {
|
|
||||||
parser := getGlobalParser()
|
|
||||||
input := &parsers.CredentialInput{
|
|
||||||
Username: Username,
|
|
||||||
UsersFile: UsersFile,
|
|
||||||
AddUsers: AddUsers,
|
|
||||||
}
|
|
||||||
|
|
||||||
result, err := parser.credentialParser.Parse(input, parser.options)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新全局变量
|
|
||||||
if len(result.Config.Credentials.Usernames) > 0 {
|
|
||||||
for serviceName := range Userdict {
|
|
||||||
Userdict[serviceName] = result.Config.Credentials.Usernames
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParsePass 解析密码配置 - 兼容接口
|
|
||||||
func ParsePass(Info *HostInfo) error {
|
|
||||||
parser := getGlobalParser()
|
|
||||||
|
|
||||||
// 处理密码
|
|
||||||
credInput := &parsers.CredentialInput{
|
|
||||||
Password: Password,
|
|
||||||
PasswordsFile: PasswordsFile,
|
|
||||||
AddPasswords: AddPasswords,
|
|
||||||
HashValue: HashValue,
|
|
||||||
HashFile: HashFile,
|
|
||||||
}
|
|
||||||
|
|
||||||
credResult, err := parser.credentialParser.Parse(credInput, parser.options)
|
|
||||||
if err != nil {
|
|
||||||
LogError(fmt.Sprintf("密码解析失败: %v", err))
|
|
||||||
} else if credResult.Config.Credentials != nil {
|
|
||||||
if len(credResult.Config.Credentials.Passwords) > 0 {
|
|
||||||
Passwords = credResult.Config.Credentials.Passwords
|
|
||||||
}
|
|
||||||
if len(credResult.Config.Credentials.HashValues) > 0 {
|
|
||||||
HashValues = credResult.Config.Credentials.HashValues
|
|
||||||
}
|
|
||||||
if len(credResult.Config.Credentials.HashBytes) > 0 {
|
|
||||||
HashBytes = credResult.Config.Credentials.HashBytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理URL和主机
|
|
||||||
targetInput := &parsers.TargetInput{
|
|
||||||
TargetURL: TargetURL,
|
|
||||||
URLsFile: URLsFile,
|
|
||||||
Host: Info.Host,
|
|
||||||
HostsFile: HostsFile,
|
|
||||||
Ports: Ports,
|
|
||||||
PortsFile: PortsFile,
|
|
||||||
AddPorts: AddPorts,
|
|
||||||
ExcludePorts: ExcludePorts,
|
|
||||||
}
|
|
||||||
|
|
||||||
targetResult, err := parser.targetParser.Parse(targetInput, parser.options)
|
|
||||||
if err != nil {
|
|
||||||
LogError(fmt.Sprintf("目标解析失败: %v", err))
|
|
||||||
} else if targetResult.Config.Targets != nil {
|
|
||||||
if len(targetResult.Config.Targets.URLs) > 0 {
|
|
||||||
URLs = targetResult.Config.Targets.URLs
|
|
||||||
}
|
|
||||||
if len(targetResult.Config.Targets.Hosts) > 0 {
|
|
||||||
Info.Host = joinStrings(targetResult.Config.Targets.Hosts, ",")
|
|
||||||
}
|
|
||||||
if len(targetResult.Config.Targets.Ports) > 0 {
|
|
||||||
Ports = joinInts(targetResult.Config.Targets.Ports, ",")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseInput 解析输入参数 - 兼容接口
|
|
||||||
func ParseInput(Info *HostInfo) error {
|
|
||||||
parser := getGlobalParser()
|
|
||||||
|
|
||||||
// 网络配置解析
|
|
||||||
networkInput := &parsers.NetworkInput{
|
|
||||||
HttpProxy: HttpProxy,
|
|
||||||
Socks5Proxy: Socks5Proxy,
|
|
||||||
Timeout: Timeout,
|
|
||||||
WebTimeout: WebTimeout,
|
|
||||||
DisablePing: DisablePing,
|
|
||||||
DnsLog: DnsLog,
|
|
||||||
UserAgent: UserAgent,
|
|
||||||
Cookie: Cookie,
|
|
||||||
}
|
|
||||||
|
|
||||||
networkResult, err := parser.networkParser.Parse(networkInput, parser.options)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("网络配置解析失败: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新全局变量
|
|
||||||
if networkResult.Config.Network != nil {
|
|
||||||
HttpProxy = networkResult.Config.Network.HttpProxy
|
|
||||||
Socks5Proxy = networkResult.Config.Network.Socks5Proxy
|
|
||||||
if networkResult.Config.Network.Timeout > 0 {
|
|
||||||
Timeout = int64(networkResult.Config.Network.Timeout.Seconds())
|
|
||||||
}
|
|
||||||
if networkResult.Config.Network.WebTimeout > 0 {
|
|
||||||
WebTimeout = int64(networkResult.Config.Network.WebTimeout.Seconds())
|
|
||||||
}
|
|
||||||
UserAgent = networkResult.Config.Network.UserAgent
|
|
||||||
Cookie = networkResult.Config.Network.Cookie
|
|
||||||
DisablePing = networkResult.Config.Network.DisablePing
|
|
||||||
DnsLog = networkResult.Config.Network.EnableDNSLog
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证配置
|
|
||||||
validationInput := &parsers.ValidationInput{
|
|
||||||
ScanMode: ScanMode,
|
|
||||||
LocalMode: LocalMode,
|
|
||||||
HasHosts: Info.Host != "" || HostsFile != "",
|
|
||||||
HasURLs: TargetURL != "" || URLsFile != "",
|
|
||||||
HasPorts: Ports != "" || PortsFile != "",
|
|
||||||
HasProxy: HttpProxy != "" || Socks5Proxy != "",
|
|
||||||
DisablePing: DisablePing,
|
|
||||||
}
|
|
||||||
|
|
||||||
validationResult, err := parser.validationParser.Parse(validationInput, nil, parser.options)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("参数验证失败: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 报告验证警告
|
|
||||||
for _, warning := range validationResult.Warnings {
|
|
||||||
LogBase(warning)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果有严重错误,返回错误
|
|
||||||
for _, validationError := range validationResult.Errors {
|
|
||||||
LogError(validationError.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保持原有的工具函数
|
|
||||||
|
|
||||||
// ReadFileLines 读取文件行 - 兼容接口
|
|
||||||
func ReadFileLines(filename string) ([]string, error) {
|
|
||||||
parser := getGlobalParser()
|
|
||||||
result, err := parser.fileReader.ReadFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return result.Lines, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveDuplicate 去重函数 - 保持原有实现
|
// RemoveDuplicate 去重函数 - 保持原有实现
|
||||||
func RemoveDuplicate(old []string) []string {
|
func RemoveDuplicate(old []string) []string {
|
||||||
temp := make(map[string]struct{})
|
temp := make(map[string]struct{})
|
||||||
@ -519,23 +357,6 @@ func joinInts(slice []int, sep string) string {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetParser 获取解析器实例 - 新增API
|
|
||||||
func GetParser() *Parser {
|
|
||||||
return getGlobalParser()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetParserOptions 设置解析器选项 - 新增API
|
|
||||||
func SetParserOptions(options *parsers.ParserOptions) {
|
|
||||||
globalParser = NewParser(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClearParserCache 清空解析器缓存 - 新增API
|
|
||||||
func ClearParserCache() {
|
|
||||||
if globalParser != nil && globalParser.fileReader != nil {
|
|
||||||
globalParser.fileReader.ClearCache()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// showParseSummary 显示解析结果摘要
|
// showParseSummary 显示解析结果摘要
|
||||||
func showParseSummary(config *parsers.ParsedConfig) {
|
func showParseSummary(config *parsers.ParsedConfig) {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
@ -612,7 +433,7 @@ func applyLogLevel() {
|
|||||||
if LogLevel == "" {
|
if LogLevel == "" {
|
||||||
return // 使用默认级别
|
return // 使用默认级别
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据LogLevel字符串获取对应的日志级别
|
// 根据LogLevel字符串获取对应的日志级别
|
||||||
var level logging.LogLevel
|
var level logging.LogLevel
|
||||||
switch LogLevel {
|
switch LogLevel {
|
||||||
@ -653,15 +474,15 @@ func applyLogLevel() {
|
|||||||
return // 无效的级别,保持默认
|
return // 无效的级别,保持默认
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新全局日志管理器的级别
|
// 更新全局日志管理器的级别
|
||||||
if globalLogger != nil {
|
if globalLogger != nil {
|
||||||
config := &logging.LoggerConfig{
|
config := &logging.LoggerConfig{
|
||||||
Level: level,
|
Level: level,
|
||||||
EnableColor: !NoColor,
|
EnableColor: !NoColor,
|
||||||
SlowOutput: SlowLogOutput,
|
SlowOutput: SlowLogOutput,
|
||||||
ShowProgress: true,
|
ShowProgress: true,
|
||||||
StartTime: StartTime,
|
StartTime: StartTime,
|
||||||
LevelColors: map[logging.LogLevel]color.Attribute{
|
LevelColors: map[logging.LogLevel]color.Attribute{
|
||||||
logging.LevelError: color.FgBlue,
|
logging.LevelError: color.FgBlue,
|
||||||
logging.LevelBase: color.FgYellow,
|
logging.LevelBase: color.FgYellow,
|
||||||
@ -670,15 +491,15 @@ func applyLogLevel() {
|
|||||||
logging.LevelDebug: color.FgWhite,
|
logging.LevelDebug: color.FgWhite,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
newLogger := logging.NewLogger(config)
|
newLogger := logging.NewLogger(config)
|
||||||
if ProgressBar != nil {
|
if ProgressBar != nil {
|
||||||
newLogger.SetProgressBar(ProgressBar)
|
newLogger.SetProgressBar(ProgressBar)
|
||||||
}
|
}
|
||||||
newLogger.SetOutputMutex(&OutputMutex)
|
newLogger.SetOutputMutex(&OutputMutex)
|
||||||
|
|
||||||
// 更新全局日志管理器
|
// 更新全局日志管理器
|
||||||
globalLogger = newLogger
|
globalLogger = newLogger
|
||||||
status = newLogger.GetScanStatus()
|
status = newLogger.GetScanStatus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,66 +1,7 @@
|
|||||||
package Common
|
package Common
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 预定义端口组常量
|
// 预定义端口组常量
|
||||||
var (
|
var (
|
||||||
ServicePorts = "21,22,23,25,110,135,139,143,162,389,445,465,502,587,636,873,993,995,1433,1521,2222,3306,3389,5020,5432,5672,5671,6379,8161,8443,9000,9092,9093,9200,10051,11211,15672,15671,27017,61616,61613"
|
WebPorts = "80,81,82,83,84,85,86,87,88,89,90,91,92,98,99,443,800,801,808,880,888,889,1000,1010,1080,1081,1082,1099,1118,1888,2008,2020,2100,2375,2379,3000,3008,3128,3505,5555,6080,6648,6868,7000,7001,7002,7003,7004,7005,7007,7008,7070,7071,7074,7078,7080,7088,7200,7680,7687,7688,7777,7890,8000,8001,8002,8003,8004,8005,8006,8008,8009,8010,8011,8012,8016,8018,8020,8028,8030,8038,8042,8044,8046,8048,8053,8060,8069,8070,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8108,8118,8161,8172,8180,8181,8200,8222,8244,8258,8280,8288,8300,8360,8443,8448,8484,8800,8834,8838,8848,8858,8868,8879,8880,8881,8888,8899,8983,8989,9000,9001,9002,9008,9010,9043,9060,9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9200,9443,9448,9800,9981,9986,9988,9998,9999,10000,10001,10002,10004,10008,10010,10051,10250,12018,12443,14000,15672,15671,16080,18000,18001,18002,18004,18008,18080,18082,18088,18090,18098,19001,20000,20720,20880,21000,21501,21502,28018"
|
||||||
DbPorts = "1433,1521,3306,5432,5672,6379,7687,9042,9093,9200,11211,27017,61616"
|
MainPorts = "21,22,23,80,81,110,135,139,143,389,443,445,502,873,993,995,1433,1521,3306,5432,5672,6379,7001,7687,8000,8005,8009,8080,8089,8443,9000,9042,9092,9200,10051,11211,15672,27017,61616"
|
||||||
WebPorts = "80,81,82,83,84,85,86,87,88,89,90,91,92,98,99,443,800,801,808,880,888,889,1000,1010,1080,1081,1082,1099,1118,1888,2008,2020,2100,2375,2379,3000,3008,3128,3505,5555,6080,6648,6868,7000,7001,7002,7003,7004,7005,7007,7008,7070,7071,7074,7078,7080,7088,7200,7680,7687,7688,7777,7890,8000,8001,8002,8003,8004,8005,8006,8008,8009,8010,8011,8012,8016,8018,8020,8028,8030,8038,8042,8044,8046,8048,8053,8060,8069,8070,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8108,8118,8161,8172,8180,8181,8200,8222,8244,8258,8280,8288,8300,8360,8443,8448,8484,8800,8834,8838,8848,8858,8868,8879,8880,8881,8888,8899,8983,8989,9000,9001,9002,9008,9010,9043,9060,9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9200,9443,9448,9800,9981,9986,9988,9998,9999,10000,10001,10002,10004,10008,10010,10051,10250,12018,12443,14000,15672,15671,16080,18000,18001,18002,18004,18008,18080,18082,18088,18090,18098,19001,20000,20720,20880,21000,21501,21502,28018"
|
|
||||||
AllPorts = "1-65535"
|
|
||||||
MainPorts = "21,22,23,80,81,110,135,139,143,389,443,445,502,873,993,995,1433,1521,3306,5432,5672,6379,7001,7687,8000,8005,8009,8080,8089,8443,9000,9042,9092,9200,10051,11211,15672,27017,61616"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsValidPort 检查端口号是否有效
|
|
||||||
func IsValidPort(port int) bool {
|
|
||||||
return port >= 1 && port <= 65535
|
|
||||||
}
|
|
||||||
|
|
||||||
// removeDuplicates 移除重复的端口号并排序
|
|
||||||
func removeDuplicates(slice []int) []int {
|
|
||||||
if len(slice) == 0 {
|
|
||||||
return slice
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建一个map来跟踪已见过的端口
|
|
||||||
seen := make(map[int]bool)
|
|
||||||
var result []int
|
|
||||||
|
|
||||||
for _, port := range slice {
|
|
||||||
if !seen[port] {
|
|
||||||
seen[port] = true
|
|
||||||
result = append(result, port)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 排序
|
|
||||||
sort.Ints(result)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParsePortsFromString 从逗号分隔的字符串解析端口列表
|
|
||||||
func ParsePortsFromString(portsStr string) []int {
|
|
||||||
if portsStr == "" {
|
|
||||||
return []int{}
|
|
||||||
}
|
|
||||||
|
|
||||||
var ports []int
|
|
||||||
portStrs := strings.Split(portsStr, ",")
|
|
||||||
|
|
||||||
for _, portStr := range portStrs {
|
|
||||||
portStr = strings.TrimSpace(portStr)
|
|
||||||
if portStr == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if port, err := strconv.Atoi(portStr); err == nil && IsValidPort(port) {
|
|
||||||
ports = append(ports, port)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return removeDuplicates(ports)
|
|
||||||
}
|
|
||||||
|
@ -9,29 +9,29 @@ import (
|
|||||||
|
|
||||||
// Manager 配置管理器,统一管理所有配置
|
// Manager 配置管理器,统一管理所有配置
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
config *Config
|
config *Config
|
||||||
serviceDict *ServiceDictionary
|
serviceDict *ServiceDictionary
|
||||||
probeMapping *ProbeMapping
|
probeMapping *ProbeMapping
|
||||||
scanOptions *ScanOptionsManager
|
scanOptions *ScanOptionsManager
|
||||||
initialized bool
|
initialized bool
|
||||||
lastUpdate time.Time
|
lastUpdate time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManager 创建配置管理器
|
// NewManager 创建配置管理器
|
||||||
func NewManager() *Manager {
|
func NewManager() *Manager {
|
||||||
m := &Manager{
|
m := &Manager{
|
||||||
config: NewConfig(),
|
config: NewConfig(),
|
||||||
serviceDict: NewServiceDictionary(),
|
serviceDict: NewServiceDictionary(),
|
||||||
probeMapping: NewProbeMapping(),
|
probeMapping: NewProbeMapping(),
|
||||||
scanOptions: NewScanOptionsManager(),
|
scanOptions: NewScanOptionsManager(),
|
||||||
initialized: true,
|
initialized: true,
|
||||||
lastUpdate: time.Now(),
|
lastUpdate: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置默认值
|
// 设置默认值
|
||||||
m.scanOptions.SetDefaults()
|
m.scanOptions.SetDefaults()
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ func NewManager() *Manager {
|
|||||||
func (m *Manager) GetConfig() *Config {
|
func (m *Manager) GetConfig() *Config {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
return m.scanOptions.GetConfig()
|
return m.scanOptions.GetConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ func (m *Manager) GetConfig() *Config {
|
|||||||
func (m *Manager) SetConfig(config *Config) {
|
func (m *Manager) SetConfig(config *Config) {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
if config != nil {
|
if config != nil {
|
||||||
m.scanOptions.SetConfig(config)
|
m.scanOptions.SetConfig(config)
|
||||||
m.config = config
|
m.config = config
|
||||||
@ -59,7 +59,7 @@ func (m *Manager) SetConfig(config *Config) {
|
|||||||
func (m *Manager) GetServiceDictionary() *ServiceDictionary {
|
func (m *Manager) GetServiceDictionary() *ServiceDictionary {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
return m.serviceDict
|
return m.serviceDict
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ func (m *Manager) GetServiceDictionary() *ServiceDictionary {
|
|||||||
func (m *Manager) GetProbeMapping() *ProbeMapping {
|
func (m *Manager) GetProbeMapping() *ProbeMapping {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
return m.probeMapping
|
return m.probeMapping
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ func (m *Manager) GetProbeMapping() *ProbeMapping {
|
|||||||
func (m *Manager) GetScanOptions() *ScanOptionsManager {
|
func (m *Manager) GetScanOptions() *ScanOptionsManager {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
return m.scanOptions
|
return m.scanOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ func (m *Manager) GetScanOptions() *ScanOptionsManager {
|
|||||||
func (m *Manager) SetProgressBar(pb *progressbar.ProgressBar) {
|
func (m *Manager) SetProgressBar(pb *progressbar.ProgressBar) {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
if m.config.Application != nil {
|
if m.config.Application != nil {
|
||||||
m.config.Application.ProgressBar = pb
|
m.config.Application.ProgressBar = pb
|
||||||
m.lastUpdate = time.Now()
|
m.lastUpdate = time.Now()
|
||||||
@ -94,7 +94,7 @@ func (m *Manager) SetProgressBar(pb *progressbar.ProgressBar) {
|
|||||||
func (m *Manager) GetProgressBar() *progressbar.ProgressBar {
|
func (m *Manager) GetProgressBar() *progressbar.ProgressBar {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
if m.config.Application != nil {
|
if m.config.Application != nil {
|
||||||
return m.config.Application.ProgressBar
|
return m.config.Application.ProgressBar
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ func (m *Manager) GetProgressBar() *progressbar.ProgressBar {
|
|||||||
func (m *Manager) GetVersion() string {
|
func (m *Manager) GetVersion() string {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
return m.config.Application.Version.Full
|
return m.config.Application.Version.Full
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ func (m *Manager) GetVersion() string {
|
|||||||
func (m *Manager) SetVersion(version string) {
|
func (m *Manager) SetVersion(version string) {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
if m.config.Application != nil {
|
if m.config.Application != nil {
|
||||||
m.config.Application.Version.Full = version
|
m.config.Application.Version.Full = version
|
||||||
m.lastUpdate = time.Now()
|
m.lastUpdate = time.Now()
|
||||||
@ -124,7 +124,7 @@ func (m *Manager) SetVersion(version string) {
|
|||||||
func (m *Manager) GetOutputMutex() *sync.Mutex {
|
func (m *Manager) GetOutputMutex() *sync.Mutex {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
if m.config.Application != nil {
|
if m.config.Application != nil {
|
||||||
return &m.config.Application.OutputMutex
|
return &m.config.Application.OutputMutex
|
||||||
}
|
}
|
||||||
@ -135,11 +135,11 @@ func (m *Manager) GetOutputMutex() *sync.Mutex {
|
|||||||
func (m *Manager) SetDefaults() {
|
func (m *Manager) SetDefaults() {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
m.scanOptions.SetDefaults()
|
m.scanOptions.SetDefaults()
|
||||||
m.serviceDict.ResetToDefaults()
|
m.serviceDict.ResetToDefaults()
|
||||||
m.probeMapping.ResetToDefaults()
|
m.probeMapping.ResetToDefaults()
|
||||||
|
|
||||||
// 设置应用程序默认值
|
// 设置应用程序默认值
|
||||||
if m.config.Application != nil {
|
if m.config.Application != nil {
|
||||||
m.config.Application.Version = Version{
|
m.config.Application.Version = Version{
|
||||||
@ -149,7 +149,7 @@ func (m *Manager) SetDefaults() {
|
|||||||
Full: "2.0.2",
|
Full: "2.0.2",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m.lastUpdate = time.Now()
|
m.lastUpdate = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,14 +157,14 @@ func (m *Manager) SetDefaults() {
|
|||||||
func (m *Manager) ValidateAll() []string {
|
func (m *Manager) ValidateAll() []string {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
var warnings []string
|
var warnings []string
|
||||||
|
|
||||||
// 验证扫描选项
|
// 验证扫描选项
|
||||||
warnings = append(warnings, m.scanOptions.ValidateConfig()...)
|
warnings = append(warnings, m.scanOptions.ValidateConfig()...)
|
||||||
|
|
||||||
// 可以添加其他模块的验证逻辑
|
// 可以添加其他模块的验证逻辑
|
||||||
|
|
||||||
return warnings
|
return warnings
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,16 +172,16 @@ func (m *Manager) ValidateAll() []string {
|
|||||||
func (m *Manager) GetSummary() map[string]interface{} {
|
func (m *Manager) GetSummary() map[string]interface{} {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
summary := m.scanOptions.GetSummary()
|
summary := m.scanOptions.GetSummary()
|
||||||
|
|
||||||
// 添加其他模块信息
|
// 添加其他模块信息
|
||||||
summary["service_count"] = len(m.serviceDict.GetServiceNames())
|
summary["service_count"] = len(m.serviceDict.GetServiceNames())
|
||||||
summary["password_count"] = m.serviceDict.GetPasswordCount()
|
summary["password_count"] = m.serviceDict.GetPasswordCount()
|
||||||
summary["mapped_ports_count"] = len(m.probeMapping.GetMappedPorts())
|
summary["mapped_ports_count"] = len(m.probeMapping.GetMappedPorts())
|
||||||
summary["version"] = m.GetVersion()
|
summary["version"] = m.GetVersion()
|
||||||
summary["last_updated"] = m.lastUpdate
|
summary["last_updated"] = m.lastUpdate
|
||||||
|
|
||||||
return summary
|
return summary
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ func (m *Manager) GetSummary() map[string]interface{} {
|
|||||||
func (m *Manager) Reset() {
|
func (m *Manager) Reset() {
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
m.config = NewConfig()
|
m.config = NewConfig()
|
||||||
m.serviceDict.ResetToDefaults()
|
m.serviceDict.ResetToDefaults()
|
||||||
m.probeMapping.ResetToDefaults()
|
m.probeMapping.ResetToDefaults()
|
||||||
@ -202,7 +202,7 @@ func (m *Manager) Reset() {
|
|||||||
func (m *Manager) IsInitialized() bool {
|
func (m *Manager) IsInitialized() bool {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
return m.initialized
|
return m.initialized
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ func (m *Manager) IsInitialized() bool {
|
|||||||
func (m *Manager) GetLastUpdate() time.Time {
|
func (m *Manager) GetLastUpdate() time.Time {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
return m.lastUpdate
|
return m.lastUpdate
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,28 +228,6 @@ func GetGlobalManager() *Manager {
|
|||||||
return globalManager
|
return globalManager
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGlobalManager 设置全局配置管理器实例
|
|
||||||
func SetGlobalManager(manager *Manager) {
|
|
||||||
globalManager = manager
|
|
||||||
}
|
|
||||||
|
|
||||||
// 便利函数,直接使用全局实例
|
|
||||||
|
|
||||||
// GetGlobalConfig 获取全局配置
|
|
||||||
func GetGlobalManagerConfig() *Config {
|
|
||||||
return GetGlobalManager().GetConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGlobalManagerConfig 设置全局配置
|
|
||||||
func SetGlobalManagerConfig(config *Config) {
|
|
||||||
GetGlobalManager().SetConfig(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetGlobalVersion 获取全局版本信息
|
|
||||||
func GetGlobalVersion() string {
|
|
||||||
return GetGlobalManager().GetVersion()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGlobalVersion 设置全局版本信息
|
// SetGlobalVersion 设置全局版本信息
|
||||||
func SetGlobalVersion(version string) {
|
func SetGlobalVersion(version string) {
|
||||||
GetGlobalManager().SetVersion(version)
|
GetGlobalManager().SetVersion(version)
|
||||||
@ -259,28 +237,3 @@ func SetGlobalVersion(version string) {
|
|||||||
func GetGlobalProgressBar() *progressbar.ProgressBar {
|
func GetGlobalProgressBar() *progressbar.ProgressBar {
|
||||||
return GetGlobalManager().GetProgressBar()
|
return GetGlobalManager().GetProgressBar()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGlobalProgressBar 设置全局进度条
|
|
||||||
func SetGlobalProgressBar(pb *progressbar.ProgressBar) {
|
|
||||||
GetGlobalManager().SetProgressBar(pb)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetGlobalOutputMutex 获取全局输出互斥锁
|
|
||||||
func GetGlobalOutputMutex() *sync.Mutex {
|
|
||||||
return GetGlobalManager().GetOutputMutex()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGlobalDefaults 设置全局默认值
|
|
||||||
func SetGlobalManagerDefaults() {
|
|
||||||
GetGlobalManager().SetDefaults()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateAllGlobal 验证全局配置
|
|
||||||
func ValidateAllGlobal() []string {
|
|
||||||
return GetGlobalManager().ValidateAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetGlobalManagerSummary 获取全局配置摘要
|
|
||||||
func GetGlobalManagerSummary() map[string]interface{} {
|
|
||||||
return GetGlobalManager().GetSummary()
|
|
||||||
}
|
|
@ -178,14 +178,14 @@ func getDefaultPortMap() map[int][]string {
|
|||||||
func (pm *ProbeMapping) GetProbesForPort(port int) []string {
|
func (pm *ProbeMapping) GetProbesForPort(port int) []string {
|
||||||
pm.mu.RLock()
|
pm.mu.RLock()
|
||||||
defer pm.mu.RUnlock()
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
if probes, exists := pm.portMap[port]; exists {
|
if probes, exists := pm.portMap[port]; exists {
|
||||||
// 返回副本,避免外部修改
|
// 返回副本,避免外部修改
|
||||||
result := make([]string, len(probes))
|
result := make([]string, len(probes))
|
||||||
copy(result, probes)
|
copy(result, probes)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回默认探测器
|
// 返回默认探测器
|
||||||
result := make([]string, len(pm.defaultMap))
|
result := make([]string, len(pm.defaultMap))
|
||||||
copy(result, pm.defaultMap)
|
copy(result, pm.defaultMap)
|
||||||
@ -196,7 +196,7 @@ func (pm *ProbeMapping) GetProbesForPort(port int) []string {
|
|||||||
func (pm *ProbeMapping) SetProbesForPort(port int, probes []string) {
|
func (pm *ProbeMapping) SetProbesForPort(port int, probes []string) {
|
||||||
pm.mu.Lock()
|
pm.mu.Lock()
|
||||||
defer pm.mu.Unlock()
|
defer pm.mu.Unlock()
|
||||||
|
|
||||||
if len(probes) > 0 {
|
if len(probes) > 0 {
|
||||||
// 创建副本
|
// 创建副本
|
||||||
probesCopy := make([]string, len(probes))
|
probesCopy := make([]string, len(probes))
|
||||||
@ -211,11 +211,11 @@ func (pm *ProbeMapping) SetProbesForPort(port int, probes []string) {
|
|||||||
func (pm *ProbeMapping) AddProbeToPort(port int, probe string) {
|
func (pm *ProbeMapping) AddProbeToPort(port int, probe string) {
|
||||||
pm.mu.Lock()
|
pm.mu.Lock()
|
||||||
defer pm.mu.Unlock()
|
defer pm.mu.Unlock()
|
||||||
|
|
||||||
if probe == "" {
|
if probe == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if existing, exists := pm.portMap[port]; exists {
|
if existing, exists := pm.portMap[port]; exists {
|
||||||
// 检查是否已存在
|
// 检查是否已存在
|
||||||
for _, p := range existing {
|
for _, p := range existing {
|
||||||
@ -235,7 +235,7 @@ func (pm *ProbeMapping) AddProbeToPort(port int, probe string) {
|
|||||||
func (pm *ProbeMapping) RemoveProbeFromPort(port int, probe string) {
|
func (pm *ProbeMapping) RemoveProbeFromPort(port int, probe string) {
|
||||||
pm.mu.Lock()
|
pm.mu.Lock()
|
||||||
defer pm.mu.Unlock()
|
defer pm.mu.Unlock()
|
||||||
|
|
||||||
if existing, exists := pm.portMap[port]; exists {
|
if existing, exists := pm.portMap[port]; exists {
|
||||||
var result []string
|
var result []string
|
||||||
for _, p := range existing {
|
for _, p := range existing {
|
||||||
@ -243,7 +243,7 @@ func (pm *ProbeMapping) RemoveProbeFromPort(port int, probe string) {
|
|||||||
result = append(result, p)
|
result = append(result, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(result) > 0 {
|
if len(result) > 0 {
|
||||||
pm.portMap[port] = result
|
pm.portMap[port] = result
|
||||||
} else {
|
} else {
|
||||||
@ -256,7 +256,7 @@ func (pm *ProbeMapping) RemoveProbeFromPort(port int, probe string) {
|
|||||||
func (pm *ProbeMapping) GetDefaultProbes() []string {
|
func (pm *ProbeMapping) GetDefaultProbes() []string {
|
||||||
pm.mu.RLock()
|
pm.mu.RLock()
|
||||||
defer pm.mu.RUnlock()
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
result := make([]string, len(pm.defaultMap))
|
result := make([]string, len(pm.defaultMap))
|
||||||
copy(result, pm.defaultMap)
|
copy(result, pm.defaultMap)
|
||||||
return result
|
return result
|
||||||
@ -266,7 +266,7 @@ func (pm *ProbeMapping) GetDefaultProbes() []string {
|
|||||||
func (pm *ProbeMapping) SetDefaultProbes(probes []string) {
|
func (pm *ProbeMapping) SetDefaultProbes(probes []string) {
|
||||||
pm.mu.Lock()
|
pm.mu.Lock()
|
||||||
defer pm.mu.Unlock()
|
defer pm.mu.Unlock()
|
||||||
|
|
||||||
if len(probes) > 0 {
|
if len(probes) > 0 {
|
||||||
defaultCopy := make([]string, len(probes))
|
defaultCopy := make([]string, len(probes))
|
||||||
copy(defaultCopy, probes)
|
copy(defaultCopy, probes)
|
||||||
@ -278,7 +278,7 @@ func (pm *ProbeMapping) SetDefaultProbes(probes []string) {
|
|||||||
func (pm *ProbeMapping) GetAllPortMappings() map[int][]string {
|
func (pm *ProbeMapping) GetAllPortMappings() map[int][]string {
|
||||||
pm.mu.RLock()
|
pm.mu.RLock()
|
||||||
defer pm.mu.RUnlock()
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
result := make(map[int][]string)
|
result := make(map[int][]string)
|
||||||
for port, probes := range pm.portMap {
|
for port, probes := range pm.portMap {
|
||||||
probesCopy := make([]string, len(probes))
|
probesCopy := make([]string, len(probes))
|
||||||
@ -292,12 +292,12 @@ func (pm *ProbeMapping) GetAllPortMappings() map[int][]string {
|
|||||||
func (pm *ProbeMapping) GetMappedPorts() []int {
|
func (pm *ProbeMapping) GetMappedPorts() []int {
|
||||||
pm.mu.RLock()
|
pm.mu.RLock()
|
||||||
defer pm.mu.RUnlock()
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
ports := make([]int, 0, len(pm.portMap))
|
ports := make([]int, 0, len(pm.portMap))
|
||||||
for port := range pm.portMap {
|
for port := range pm.portMap {
|
||||||
ports = append(ports, port)
|
ports = append(ports, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Ints(ports)
|
sort.Ints(ports)
|
||||||
return ports
|
return ports
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ func (pm *ProbeMapping) GetMappedPorts() []int {
|
|||||||
func (pm *ProbeMapping) HasMappingForPort(port int) bool {
|
func (pm *ProbeMapping) HasMappingForPort(port int) bool {
|
||||||
pm.mu.RLock()
|
pm.mu.RLock()
|
||||||
defer pm.mu.RUnlock()
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
_, exists := pm.portMap[port]
|
_, exists := pm.portMap[port]
|
||||||
return exists
|
return exists
|
||||||
}
|
}
|
||||||
@ -315,7 +315,7 @@ func (pm *ProbeMapping) HasMappingForPort(port int) bool {
|
|||||||
func (pm *ProbeMapping) GetProbeCount(port int) int {
|
func (pm *ProbeMapping) GetProbeCount(port int) int {
|
||||||
pm.mu.RLock()
|
pm.mu.RLock()
|
||||||
defer pm.mu.RUnlock()
|
defer pm.mu.RUnlock()
|
||||||
|
|
||||||
if probes, exists := pm.portMap[port]; exists {
|
if probes, exists := pm.portMap[port]; exists {
|
||||||
return len(probes)
|
return len(probes)
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ func (pm *ProbeMapping) GetProbeCount(port int) int {
|
|||||||
func (pm *ProbeMapping) ResetToDefaults() {
|
func (pm *ProbeMapping) ResetToDefaults() {
|
||||||
pm.mu.Lock()
|
pm.mu.Lock()
|
||||||
defer pm.mu.Unlock()
|
defer pm.mu.Unlock()
|
||||||
|
|
||||||
pm.defaultMap = getDefaultProbeMap()
|
pm.defaultMap = getDefaultProbeMap()
|
||||||
pm.portMap = getDefaultPortMap()
|
pm.portMap = getDefaultPortMap()
|
||||||
}
|
}
|
||||||
@ -335,7 +335,7 @@ func (pm *ProbeMapping) ResetToDefaults() {
|
|||||||
func (pm *ProbeMapping) ClearPortMapping(port int) {
|
func (pm *ProbeMapping) ClearPortMapping(port int) {
|
||||||
pm.mu.Lock()
|
pm.mu.Lock()
|
||||||
defer pm.mu.Unlock()
|
defer pm.mu.Unlock()
|
||||||
|
|
||||||
delete(pm.portMap, port)
|
delete(pm.portMap, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,7 +343,7 @@ func (pm *ProbeMapping) ClearPortMapping(port int) {
|
|||||||
func (pm *ProbeMapping) ClearAllMappings() {
|
func (pm *ProbeMapping) ClearAllMappings() {
|
||||||
pm.mu.Lock()
|
pm.mu.Lock()
|
||||||
defer pm.mu.Unlock()
|
defer pm.mu.Unlock()
|
||||||
|
|
||||||
pm.portMap = make(map[int][]string)
|
pm.portMap = make(map[int][]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,30 +360,3 @@ func GetGlobalProbeMapping() *ProbeMapping {
|
|||||||
})
|
})
|
||||||
return globalProbeMapping
|
return globalProbeMapping
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGlobalProbeMapping 设置全局探测器映射实例
|
|
||||||
func SetGlobalProbeMapping(mapping *ProbeMapping) {
|
|
||||||
globalProbeMapping = mapping
|
|
||||||
}
|
|
||||||
|
|
||||||
// 便利函数,直接使用全局实例
|
|
||||||
|
|
||||||
// GetProbesForPort 获取指定端口的探测器列表(全局函数)
|
|
||||||
func GetProbesForPort(port int) []string {
|
|
||||||
return GetGlobalProbeMapping().GetProbesForPort(port)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDefaultProbes 获取默认探测器列表(全局函数)
|
|
||||||
func GetDefaultProbes() []string {
|
|
||||||
return GetGlobalProbeMapping().GetDefaultProbes()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetProbesForPort 设置指定端口的探测器列表(全局函数)
|
|
||||||
func SetProbesForPort(port int, probes []string) {
|
|
||||||
GetGlobalProbeMapping().SetProbesForPort(port, probes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMappedPorts 获取所有已映射的端口列表(全局函数)
|
|
||||||
func GetMappedPorts() []int {
|
|
||||||
return GetGlobalProbeMapping().GetMappedPorts()
|
|
||||||
}
|
|
@ -22,7 +22,7 @@ func NewScanOptionsManager() *ScanOptionsManager {
|
|||||||
func (som *ScanOptionsManager) GetConfig() *Config {
|
func (som *ScanOptionsManager) GetConfig() *Config {
|
||||||
som.mu.RLock()
|
som.mu.RLock()
|
||||||
defer som.mu.RUnlock()
|
defer som.mu.RUnlock()
|
||||||
|
|
||||||
// 返回深拷贝,避免外部修改
|
// 返回深拷贝,避免外部修改
|
||||||
return som.copyConfig(som.options)
|
return som.copyConfig(som.options)
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ func (som *ScanOptionsManager) GetConfig() *Config {
|
|||||||
func (som *ScanOptionsManager) SetConfig(config *Config) {
|
func (som *ScanOptionsManager) SetConfig(config *Config) {
|
||||||
som.mu.Lock()
|
som.mu.Lock()
|
||||||
defer som.mu.Unlock()
|
defer som.mu.Unlock()
|
||||||
|
|
||||||
if config != nil {
|
if config != nil {
|
||||||
som.options = som.copyConfig(config)
|
som.options = som.copyConfig(config)
|
||||||
som.options.LastUpdated = time.Now()
|
som.options.LastUpdated = time.Now()
|
||||||
@ -42,7 +42,7 @@ func (som *ScanOptionsManager) SetConfig(config *Config) {
|
|||||||
func (som *ScanOptionsManager) UpdateScanTarget(target *ScanTargetConfig) {
|
func (som *ScanOptionsManager) UpdateScanTarget(target *ScanTargetConfig) {
|
||||||
som.mu.Lock()
|
som.mu.Lock()
|
||||||
defer som.mu.Unlock()
|
defer som.mu.Unlock()
|
||||||
|
|
||||||
if target != nil {
|
if target != nil {
|
||||||
som.options.ScanTarget = target
|
som.options.ScanTarget = target
|
||||||
som.options.LastUpdated = time.Now()
|
som.options.LastUpdated = time.Now()
|
||||||
@ -53,7 +53,7 @@ func (som *ScanOptionsManager) UpdateScanTarget(target *ScanTargetConfig) {
|
|||||||
func (som *ScanOptionsManager) UpdateCredential(credential *CredentialConfig) {
|
func (som *ScanOptionsManager) UpdateCredential(credential *CredentialConfig) {
|
||||||
som.mu.Lock()
|
som.mu.Lock()
|
||||||
defer som.mu.Unlock()
|
defer som.mu.Unlock()
|
||||||
|
|
||||||
if credential != nil {
|
if credential != nil {
|
||||||
som.options.Credential = credential
|
som.options.Credential = credential
|
||||||
som.options.LastUpdated = time.Now()
|
som.options.LastUpdated = time.Now()
|
||||||
@ -64,7 +64,7 @@ func (som *ScanOptionsManager) UpdateCredential(credential *CredentialConfig) {
|
|||||||
func (som *ScanOptionsManager) UpdateScanControl(control *ScanControlConfig) {
|
func (som *ScanOptionsManager) UpdateScanControl(control *ScanControlConfig) {
|
||||||
som.mu.Lock()
|
som.mu.Lock()
|
||||||
defer som.mu.Unlock()
|
defer som.mu.Unlock()
|
||||||
|
|
||||||
if control != nil {
|
if control != nil {
|
||||||
som.options.ScanControl = control
|
som.options.ScanControl = control
|
||||||
som.options.LastUpdated = time.Now()
|
som.options.LastUpdated = time.Now()
|
||||||
@ -75,7 +75,7 @@ func (som *ScanOptionsManager) UpdateScanControl(control *ScanControlConfig) {
|
|||||||
func (som *ScanOptionsManager) UpdateWebScan(webScan *WebScanConfig) {
|
func (som *ScanOptionsManager) UpdateWebScan(webScan *WebScanConfig) {
|
||||||
som.mu.Lock()
|
som.mu.Lock()
|
||||||
defer som.mu.Unlock()
|
defer som.mu.Unlock()
|
||||||
|
|
||||||
if webScan != nil {
|
if webScan != nil {
|
||||||
som.options.WebScan = webScan
|
som.options.WebScan = webScan
|
||||||
som.options.LastUpdated = time.Now()
|
som.options.LastUpdated = time.Now()
|
||||||
@ -86,7 +86,7 @@ func (som *ScanOptionsManager) UpdateWebScan(webScan *WebScanConfig) {
|
|||||||
func (som *ScanOptionsManager) UpdateDisplay(display *DisplayConfig) {
|
func (som *ScanOptionsManager) UpdateDisplay(display *DisplayConfig) {
|
||||||
som.mu.Lock()
|
som.mu.Lock()
|
||||||
defer som.mu.Unlock()
|
defer som.mu.Unlock()
|
||||||
|
|
||||||
if display != nil {
|
if display != nil {
|
||||||
som.options.Display = display
|
som.options.Display = display
|
||||||
som.options.LastUpdated = time.Now()
|
som.options.LastUpdated = time.Now()
|
||||||
@ -97,7 +97,7 @@ func (som *ScanOptionsManager) UpdateDisplay(display *DisplayConfig) {
|
|||||||
func (som *ScanOptionsManager) UpdateOutput(output *OutputConfig) {
|
func (som *ScanOptionsManager) UpdateOutput(output *OutputConfig) {
|
||||||
som.mu.Lock()
|
som.mu.Lock()
|
||||||
defer som.mu.Unlock()
|
defer som.mu.Unlock()
|
||||||
|
|
||||||
if output != nil {
|
if output != nil {
|
||||||
som.options.Output = output
|
som.options.Output = output
|
||||||
som.options.LastUpdated = time.Now()
|
som.options.LastUpdated = time.Now()
|
||||||
@ -108,7 +108,7 @@ func (som *ScanOptionsManager) UpdateOutput(output *OutputConfig) {
|
|||||||
func (som *ScanOptionsManager) SetDefaults() {
|
func (som *ScanOptionsManager) SetDefaults() {
|
||||||
som.mu.Lock()
|
som.mu.Lock()
|
||||||
defer som.mu.Unlock()
|
defer som.mu.Unlock()
|
||||||
|
|
||||||
// 设置扫描控制默认值
|
// 设置扫描控制默认值
|
||||||
if som.options.ScanControl.ThreadNum <= 0 {
|
if som.options.ScanControl.ThreadNum <= 0 {
|
||||||
som.options.ScanControl.ThreadNum = 600
|
som.options.ScanControl.ThreadNum = 600
|
||||||
@ -122,17 +122,17 @@ func (som *ScanOptionsManager) SetDefaults() {
|
|||||||
if som.options.ScanControl.GlobalTimeout <= 0 {
|
if som.options.ScanControl.GlobalTimeout <= 0 {
|
||||||
som.options.ScanControl.GlobalTimeout = 300 // 5分钟
|
som.options.ScanControl.GlobalTimeout = 300 // 5分钟
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置Web扫描默认值
|
// 设置Web扫描默认值
|
||||||
if som.options.WebScan.WebTimeout <= 0 {
|
if som.options.WebScan.WebTimeout <= 0 {
|
||||||
som.options.WebScan.WebTimeout = 5
|
som.options.WebScan.WebTimeout = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置暴力破解默认值
|
// 设置暴力破解默认值
|
||||||
if som.options.BruteForce.MaxRetries <= 0 {
|
if som.options.BruteForce.MaxRetries <= 0 {
|
||||||
som.options.BruteForce.MaxRetries = 3
|
som.options.BruteForce.MaxRetries = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置显示默认值
|
// 设置显示默认值
|
||||||
if som.options.Display.LogLevel == "" {
|
if som.options.Display.LogLevel == "" {
|
||||||
som.options.Display.LogLevel = "SUCCESS"
|
som.options.Display.LogLevel = "SUCCESS"
|
||||||
@ -140,7 +140,7 @@ func (som *ScanOptionsManager) SetDefaults() {
|
|||||||
if som.options.Display.Language == "" {
|
if som.options.Display.Language == "" {
|
||||||
som.options.Display.Language = "zh"
|
som.options.Display.Language = "zh"
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置输出默认值
|
// 设置输出默认值
|
||||||
if som.options.Output.OutputFormat == "" {
|
if som.options.Output.OutputFormat == "" {
|
||||||
som.options.Output.OutputFormat = "txt"
|
som.options.Output.OutputFormat = "txt"
|
||||||
@ -148,7 +148,7 @@ func (som *ScanOptionsManager) SetDefaults() {
|
|||||||
if som.options.Output.Outputfile == "" {
|
if som.options.Output.Outputfile == "" {
|
||||||
som.options.Output.Outputfile = "result.txt"
|
som.options.Output.Outputfile = "result.txt"
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置网络默认值
|
// 设置网络默认值
|
||||||
if som.options.Network.UserAgent == "" {
|
if som.options.Network.UserAgent == "" {
|
||||||
som.options.Network.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
|
som.options.Network.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
|
||||||
@ -159,7 +159,7 @@ func (som *ScanOptionsManager) SetDefaults() {
|
|||||||
if som.options.Network.PocNum <= 0 {
|
if som.options.Network.PocNum <= 0 {
|
||||||
som.options.Network.PocNum = 20
|
som.options.Network.PocNum = 20
|
||||||
}
|
}
|
||||||
|
|
||||||
som.options.LastUpdated = time.Now()
|
som.options.LastUpdated = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,33 +167,33 @@ func (som *ScanOptionsManager) SetDefaults() {
|
|||||||
func (som *ScanOptionsManager) ValidateConfig() []string {
|
func (som *ScanOptionsManager) ValidateConfig() []string {
|
||||||
som.mu.RLock()
|
som.mu.RLock()
|
||||||
defer som.mu.RUnlock()
|
defer som.mu.RUnlock()
|
||||||
|
|
||||||
var warnings []string
|
var warnings []string
|
||||||
|
|
||||||
// 验证线程数配置
|
// 验证线程数配置
|
||||||
if som.options.ScanControl.ThreadNum > 1000 {
|
if som.options.ScanControl.ThreadNum > 1000 {
|
||||||
warnings = append(warnings, "线程数过大,可能影响系统性能")
|
warnings = append(warnings, "线程数过大,可能影响系统性能")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证超时配置
|
// 验证超时配置
|
||||||
if som.options.ScanControl.Timeout > som.options.WebScan.WebTimeout {
|
if som.options.ScanControl.Timeout > som.options.WebScan.WebTimeout {
|
||||||
warnings = append(warnings, "Web超时时间大于普通超时时间,可能导致不期望的行为")
|
warnings = append(warnings, "Web超时时间大于普通超时时间,可能导致不期望的行为")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证超时配置合理性
|
// 验证超时配置合理性
|
||||||
if som.options.ScanControl.Timeout < 1 {
|
if som.options.ScanControl.Timeout < 1 {
|
||||||
warnings = append(warnings, "超时时间过短,可能导致误报")
|
warnings = append(warnings, "超时时间过短,可能导致误报")
|
||||||
}
|
}
|
||||||
|
|
||||||
if som.options.WebScan.WebTimeout < 1 {
|
if som.options.WebScan.WebTimeout < 1 {
|
||||||
warnings = append(warnings, "Web超时时间过短,可能导致误报")
|
warnings = append(warnings, "Web超时时间过短,可能导致误报")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证全局超时
|
// 验证全局超时
|
||||||
if som.options.ScanControl.GlobalTimeout < 60 {
|
if som.options.ScanControl.GlobalTimeout < 60 {
|
||||||
warnings = append(warnings, "全局超时时间过短,扫描可能提前终止")
|
warnings = append(warnings, "全局超时时间过短,扫描可能提前终止")
|
||||||
}
|
}
|
||||||
|
|
||||||
return warnings
|
return warnings
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,19 +201,19 @@ func (som *ScanOptionsManager) ValidateConfig() []string {
|
|||||||
func (som *ScanOptionsManager) GetSummary() map[string]interface{} {
|
func (som *ScanOptionsManager) GetSummary() map[string]interface{} {
|
||||||
som.mu.RLock()
|
som.mu.RLock()
|
||||||
defer som.mu.RUnlock()
|
defer som.mu.RUnlock()
|
||||||
|
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
"scan_mode": som.options.ScanControl.ScanMode,
|
"scan_mode": som.options.ScanControl.ScanMode,
|
||||||
"thread_num": som.options.ScanControl.ThreadNum,
|
"thread_num": som.options.ScanControl.ThreadNum,
|
||||||
"timeout": som.options.ScanControl.Timeout,
|
"timeout": som.options.ScanControl.Timeout,
|
||||||
"web_timeout": som.options.WebScan.WebTimeout,
|
"web_timeout": som.options.WebScan.WebTimeout,
|
||||||
"disable_ping": som.options.ScanControl.DisablePing,
|
"disable_ping": som.options.ScanControl.DisablePing,
|
||||||
"local_mode": som.options.ScanControl.LocalMode,
|
"local_mode": som.options.ScanControl.LocalMode,
|
||||||
"log_level": som.options.Display.LogLevel,
|
"log_level": som.options.Display.LogLevel,
|
||||||
"output_format": som.options.Output.OutputFormat,
|
"output_format": som.options.Output.OutputFormat,
|
||||||
"has_proxy": som.options.WebScan.HttpProxy != "" || som.options.WebScan.Socks5Proxy != "",
|
"has_proxy": som.options.WebScan.HttpProxy != "" || som.options.WebScan.Socks5Proxy != "",
|
||||||
"has_credentials": som.options.Credential.Username != "" || som.options.InputFile.UsersFile != "",
|
"has_credentials": som.options.Credential.Username != "" || som.options.InputFile.UsersFile != "",
|
||||||
"last_updated": som.options.LastUpdated,
|
"last_updated": som.options.LastUpdated,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ func (som *ScanOptionsManager) GetSummary() map[string]interface{} {
|
|||||||
func (som *ScanOptionsManager) ResetToDefaults() {
|
func (som *ScanOptionsManager) ResetToDefaults() {
|
||||||
som.mu.Lock()
|
som.mu.Lock()
|
||||||
defer som.mu.Unlock()
|
defer som.mu.Unlock()
|
||||||
|
|
||||||
som.options = NewConfig()
|
som.options = NewConfig()
|
||||||
som.SetDefaults()
|
som.SetDefaults()
|
||||||
}
|
}
|
||||||
@ -230,14 +230,14 @@ func (som *ScanOptionsManager) ResetToDefaults() {
|
|||||||
func (som *ScanOptionsManager) ClearConfig() {
|
func (som *ScanOptionsManager) ClearConfig() {
|
||||||
som.mu.Lock()
|
som.mu.Lock()
|
||||||
defer som.mu.Unlock()
|
defer som.mu.Unlock()
|
||||||
|
|
||||||
// 清空所有配置项但保持结构
|
// 清空所有配置项但保持结构
|
||||||
som.options.ScanTarget.Ports = ""
|
som.options.ScanTarget.Ports = ""
|
||||||
som.options.ScanTarget.ExcludePorts = ""
|
som.options.ScanTarget.ExcludePorts = ""
|
||||||
som.options.ScanTarget.ExcludeHosts = ""
|
som.options.ScanTarget.ExcludeHosts = ""
|
||||||
som.options.ScanTarget.AddPorts = ""
|
som.options.ScanTarget.AddPorts = ""
|
||||||
som.options.ScanTarget.HostPort = nil
|
som.options.ScanTarget.HostPort = nil
|
||||||
|
|
||||||
som.options.Credential.Username = ""
|
som.options.Credential.Username = ""
|
||||||
som.options.Credential.Password = ""
|
som.options.Credential.Password = ""
|
||||||
som.options.Credential.AddUsers = ""
|
som.options.Credential.AddUsers = ""
|
||||||
@ -248,18 +248,18 @@ func (som *ScanOptionsManager) ClearConfig() {
|
|||||||
som.options.Credential.HashBytes = nil
|
som.options.Credential.HashBytes = nil
|
||||||
som.options.Credential.HashFile = ""
|
som.options.Credential.HashFile = ""
|
||||||
som.options.Credential.SshKeyPath = ""
|
som.options.Credential.SshKeyPath = ""
|
||||||
|
|
||||||
som.options.InputFile.HostsFile = ""
|
som.options.InputFile.HostsFile = ""
|
||||||
som.options.InputFile.UsersFile = ""
|
som.options.InputFile.UsersFile = ""
|
||||||
som.options.InputFile.PasswordsFile = ""
|
som.options.InputFile.PasswordsFile = ""
|
||||||
som.options.InputFile.PortsFile = ""
|
som.options.InputFile.PortsFile = ""
|
||||||
|
|
||||||
som.options.WebScan.TargetURL = ""
|
som.options.WebScan.TargetURL = ""
|
||||||
som.options.WebScan.URLsFile = ""
|
som.options.WebScan.URLsFile = ""
|
||||||
som.options.WebScan.URLs = nil
|
som.options.WebScan.URLs = nil
|
||||||
som.options.WebScan.HttpProxy = ""
|
som.options.WebScan.HttpProxy = ""
|
||||||
som.options.WebScan.Socks5Proxy = ""
|
som.options.WebScan.Socks5Proxy = ""
|
||||||
|
|
||||||
som.options.LastUpdated = time.Now()
|
som.options.LastUpdated = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ func (som *ScanOptionsManager) copyConfig(config *Config) *Config {
|
|||||||
if config == nil {
|
if config == nil {
|
||||||
return NewConfig()
|
return NewConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
newConfig := &Config{
|
newConfig := &Config{
|
||||||
Application: &ApplicationConfig{
|
Application: &ApplicationConfig{
|
||||||
Version: config.Application.Version,
|
Version: config.Application.Version,
|
||||||
@ -355,18 +355,18 @@ func (som *ScanOptionsManager) copyConfig(config *Config) *Config {
|
|||||||
},
|
},
|
||||||
LastUpdated: config.LastUpdated,
|
LastUpdated: config.LastUpdated,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 拷贝切片
|
// 拷贝切片
|
||||||
if len(config.ScanTarget.HostPort) > 0 {
|
if len(config.ScanTarget.HostPort) > 0 {
|
||||||
newConfig.ScanTarget.HostPort = make([]string, len(config.ScanTarget.HostPort))
|
newConfig.ScanTarget.HostPort = make([]string, len(config.ScanTarget.HostPort))
|
||||||
copy(newConfig.ScanTarget.HostPort, config.ScanTarget.HostPort)
|
copy(newConfig.ScanTarget.HostPort, config.ScanTarget.HostPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(config.Credential.HashValues) > 0 {
|
if len(config.Credential.HashValues) > 0 {
|
||||||
newConfig.Credential.HashValues = make([]string, len(config.Credential.HashValues))
|
newConfig.Credential.HashValues = make([]string, len(config.Credential.HashValues))
|
||||||
copy(newConfig.Credential.HashValues, config.Credential.HashValues)
|
copy(newConfig.Credential.HashValues, config.Credential.HashValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(config.Credential.HashBytes) > 0 {
|
if len(config.Credential.HashBytes) > 0 {
|
||||||
newConfig.Credential.HashBytes = make([][]byte, len(config.Credential.HashBytes))
|
newConfig.Credential.HashBytes = make([][]byte, len(config.Credential.HashBytes))
|
||||||
for i, b := range config.Credential.HashBytes {
|
for i, b := range config.Credential.HashBytes {
|
||||||
@ -376,12 +376,12 @@ func (som *ScanOptionsManager) copyConfig(config *Config) *Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(config.WebScan.URLs) > 0 {
|
if len(config.WebScan.URLs) > 0 {
|
||||||
newConfig.WebScan.URLs = make([]string, len(config.WebScan.URLs))
|
newConfig.WebScan.URLs = make([]string, len(config.WebScan.URLs))
|
||||||
copy(newConfig.WebScan.URLs, config.WebScan.URLs)
|
copy(newConfig.WebScan.URLs, config.WebScan.URLs)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newConfig
|
return newConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,34 +400,7 @@ func GetGlobalScanOptions() *ScanOptionsManager {
|
|||||||
return globalScanOptions
|
return globalScanOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGlobalScanOptions 设置全局扫描选项管理器实例
|
|
||||||
func SetGlobalScanOptions(manager *ScanOptionsManager) {
|
|
||||||
globalScanOptions = manager
|
|
||||||
}
|
|
||||||
|
|
||||||
// 便利函数,直接使用全局实例
|
|
||||||
|
|
||||||
// GetGlobalConfig 获取全局配置
|
// GetGlobalConfig 获取全局配置
|
||||||
func GetGlobalConfig() *Config {
|
func GetGlobalConfig() *Config {
|
||||||
return GetGlobalScanOptions().GetConfig()
|
return GetGlobalScanOptions().GetConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGlobalConfig 设置全局配置
|
|
||||||
func SetGlobalConfig(config *Config) {
|
|
||||||
GetGlobalScanOptions().SetConfig(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGlobalDefaults 设置全局默认值
|
|
||||||
func SetGlobalDefaults() {
|
|
||||||
GetGlobalScanOptions().SetDefaults()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateGlobalConfig 验证全局配置
|
|
||||||
func ValidateGlobalConfig() []string {
|
|
||||||
return GetGlobalScanOptions().ValidateConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetGlobalSummary 获取全局配置摘要
|
|
||||||
func GetGlobalSummary() map[string]interface{} {
|
|
||||||
return GetGlobalScanOptions().GetSummary()
|
|
||||||
}
|
|
@ -7,10 +7,10 @@ import (
|
|||||||
|
|
||||||
// ServiceDictionary 服务字典管理器
|
// ServiceDictionary 服务字典管理器
|
||||||
type ServiceDictionary struct {
|
type ServiceDictionary struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
userDict map[string][]string
|
userDict map[string][]string
|
||||||
passwords []string
|
passwords []string
|
||||||
initialized bool
|
initialized bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServiceDictionary 创建服务字典管理器
|
// NewServiceDictionary 创建服务字典管理器
|
||||||
@ -73,7 +73,7 @@ func getDefaultPasswords() []string {
|
|||||||
func (sd *ServiceDictionary) GetUserDict(service string) []string {
|
func (sd *ServiceDictionary) GetUserDict(service string) []string {
|
||||||
sd.mu.RLock()
|
sd.mu.RLock()
|
||||||
defer sd.mu.RUnlock()
|
defer sd.mu.RUnlock()
|
||||||
|
|
||||||
service = strings.ToLower(service)
|
service = strings.ToLower(service)
|
||||||
if users, exists := sd.userDict[service]; exists {
|
if users, exists := sd.userDict[service]; exists {
|
||||||
// 返回副本,避免外部修改
|
// 返回副本,避免外部修改
|
||||||
@ -81,7 +81,7 @@ func (sd *ServiceDictionary) GetUserDict(service string) []string {
|
|||||||
copy(result, users)
|
copy(result, users)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回默认的通用用户名
|
// 返回默认的通用用户名
|
||||||
return []string{"admin", "root", "test", "user"}
|
return []string{"admin", "root", "test", "user"}
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ func (sd *ServiceDictionary) GetUserDict(service string) []string {
|
|||||||
func (sd *ServiceDictionary) SetUserDict(service string, users []string) {
|
func (sd *ServiceDictionary) SetUserDict(service string, users []string) {
|
||||||
sd.mu.Lock()
|
sd.mu.Lock()
|
||||||
defer sd.mu.Unlock()
|
defer sd.mu.Unlock()
|
||||||
|
|
||||||
service = strings.ToLower(service)
|
service = strings.ToLower(service)
|
||||||
if len(users) > 0 {
|
if len(users) > 0 {
|
||||||
// 创建副本,避免外部修改影响内部数据
|
// 创建副本,避免外部修改影响内部数据
|
||||||
@ -104,7 +104,7 @@ func (sd *ServiceDictionary) SetUserDict(service string, users []string) {
|
|||||||
func (sd *ServiceDictionary) AddUsersToService(service string, users []string) {
|
func (sd *ServiceDictionary) AddUsersToService(service string, users []string) {
|
||||||
sd.mu.Lock()
|
sd.mu.Lock()
|
||||||
defer sd.mu.Unlock()
|
defer sd.mu.Unlock()
|
||||||
|
|
||||||
service = strings.ToLower(service)
|
service = strings.ToLower(service)
|
||||||
if existing, exists := sd.userDict[service]; exists {
|
if existing, exists := sd.userDict[service]; exists {
|
||||||
// 合并并去重
|
// 合并并去重
|
||||||
@ -117,7 +117,7 @@ func (sd *ServiceDictionary) AddUsersToService(service string, users []string) {
|
|||||||
userSet[user] = struct{}{}
|
userSet[user] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转换回切片
|
// 转换回切片
|
||||||
result := make([]string, 0, len(userSet))
|
result := make([]string, 0, len(userSet))
|
||||||
for user := range userSet {
|
for user := range userSet {
|
||||||
@ -134,7 +134,7 @@ func (sd *ServiceDictionary) AddUsersToService(service string, users []string) {
|
|||||||
func (sd *ServiceDictionary) GetAllUserDicts() map[string][]string {
|
func (sd *ServiceDictionary) GetAllUserDicts() map[string][]string {
|
||||||
sd.mu.RLock()
|
sd.mu.RLock()
|
||||||
defer sd.mu.RUnlock()
|
defer sd.mu.RUnlock()
|
||||||
|
|
||||||
result := make(map[string][]string)
|
result := make(map[string][]string)
|
||||||
for service, users := range sd.userDict {
|
for service, users := range sd.userDict {
|
||||||
usersCopy := make([]string, len(users))
|
usersCopy := make([]string, len(users))
|
||||||
@ -148,7 +148,7 @@ func (sd *ServiceDictionary) GetAllUserDicts() map[string][]string {
|
|||||||
func (sd *ServiceDictionary) GetPasswords() []string {
|
func (sd *ServiceDictionary) GetPasswords() []string {
|
||||||
sd.mu.RLock()
|
sd.mu.RLock()
|
||||||
defer sd.mu.RUnlock()
|
defer sd.mu.RUnlock()
|
||||||
|
|
||||||
// 返回副本,避免外部修改
|
// 返回副本,避免外部修改
|
||||||
result := make([]string, len(sd.passwords))
|
result := make([]string, len(sd.passwords))
|
||||||
copy(result, sd.passwords)
|
copy(result, sd.passwords)
|
||||||
@ -159,7 +159,7 @@ func (sd *ServiceDictionary) GetPasswords() []string {
|
|||||||
func (sd *ServiceDictionary) SetPasswords(passwords []string) {
|
func (sd *ServiceDictionary) SetPasswords(passwords []string) {
|
||||||
sd.mu.Lock()
|
sd.mu.Lock()
|
||||||
defer sd.mu.Unlock()
|
defer sd.mu.Unlock()
|
||||||
|
|
||||||
if len(passwords) > 0 {
|
if len(passwords) > 0 {
|
||||||
// 创建副本
|
// 创建副本
|
||||||
passwordsCopy := make([]string, len(passwords))
|
passwordsCopy := make([]string, len(passwords))
|
||||||
@ -172,19 +172,19 @@ func (sd *ServiceDictionary) SetPasswords(passwords []string) {
|
|||||||
func (sd *ServiceDictionary) AddPasswords(passwords []string) {
|
func (sd *ServiceDictionary) AddPasswords(passwords []string) {
|
||||||
sd.mu.Lock()
|
sd.mu.Lock()
|
||||||
defer sd.mu.Unlock()
|
defer sd.mu.Unlock()
|
||||||
|
|
||||||
// 使用map去重
|
// 使用map去重
|
||||||
passwordSet := make(map[string]struct{})
|
passwordSet := make(map[string]struct{})
|
||||||
for _, pwd := range sd.passwords {
|
for _, pwd := range sd.passwords {
|
||||||
passwordSet[pwd] = struct{}{}
|
passwordSet[pwd] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, pwd := range passwords {
|
for _, pwd := range passwords {
|
||||||
if pwd != "" {
|
if pwd != "" {
|
||||||
passwordSet[pwd] = struct{}{}
|
passwordSet[pwd] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转换回切片
|
// 转换回切片
|
||||||
result := make([]string, 0, len(passwordSet))
|
result := make([]string, 0, len(passwordSet))
|
||||||
for pwd := range passwordSet {
|
for pwd := range passwordSet {
|
||||||
@ -197,7 +197,7 @@ func (sd *ServiceDictionary) AddPasswords(passwords []string) {
|
|||||||
func (sd *ServiceDictionary) GetServiceNames() []string {
|
func (sd *ServiceDictionary) GetServiceNames() []string {
|
||||||
sd.mu.RLock()
|
sd.mu.RLock()
|
||||||
defer sd.mu.RUnlock()
|
defer sd.mu.RUnlock()
|
||||||
|
|
||||||
services := make([]string, 0, len(sd.userDict))
|
services := make([]string, 0, len(sd.userDict))
|
||||||
for service := range sd.userDict {
|
for service := range sd.userDict {
|
||||||
services = append(services, service)
|
services = append(services, service)
|
||||||
@ -209,7 +209,7 @@ func (sd *ServiceDictionary) GetServiceNames() []string {
|
|||||||
func (sd *ServiceDictionary) HasService(service string) bool {
|
func (sd *ServiceDictionary) HasService(service string) bool {
|
||||||
sd.mu.RLock()
|
sd.mu.RLock()
|
||||||
defer sd.mu.RUnlock()
|
defer sd.mu.RUnlock()
|
||||||
|
|
||||||
_, exists := sd.userDict[strings.ToLower(service)]
|
_, exists := sd.userDict[strings.ToLower(service)]
|
||||||
return exists
|
return exists
|
||||||
}
|
}
|
||||||
@ -218,7 +218,7 @@ func (sd *ServiceDictionary) HasService(service string) bool {
|
|||||||
func (sd *ServiceDictionary) GetUserCount(service string) int {
|
func (sd *ServiceDictionary) GetUserCount(service string) int {
|
||||||
sd.mu.RLock()
|
sd.mu.RLock()
|
||||||
defer sd.mu.RUnlock()
|
defer sd.mu.RUnlock()
|
||||||
|
|
||||||
if users, exists := sd.userDict[strings.ToLower(service)]; exists {
|
if users, exists := sd.userDict[strings.ToLower(service)]; exists {
|
||||||
return len(users)
|
return len(users)
|
||||||
}
|
}
|
||||||
@ -229,7 +229,7 @@ func (sd *ServiceDictionary) GetUserCount(service string) int {
|
|||||||
func (sd *ServiceDictionary) GetPasswordCount() int {
|
func (sd *ServiceDictionary) GetPasswordCount() int {
|
||||||
sd.mu.RLock()
|
sd.mu.RLock()
|
||||||
defer sd.mu.RUnlock()
|
defer sd.mu.RUnlock()
|
||||||
|
|
||||||
return len(sd.passwords)
|
return len(sd.passwords)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ func (sd *ServiceDictionary) GetPasswordCount() int {
|
|||||||
func (sd *ServiceDictionary) ResetToDefaults() {
|
func (sd *ServiceDictionary) ResetToDefaults() {
|
||||||
sd.mu.Lock()
|
sd.mu.Lock()
|
||||||
defer sd.mu.Unlock()
|
defer sd.mu.Unlock()
|
||||||
|
|
||||||
sd.userDict = getDefaultUserDict()
|
sd.userDict = getDefaultUserDict()
|
||||||
sd.passwords = getDefaultPasswords()
|
sd.passwords = getDefaultPasswords()
|
||||||
}
|
}
|
||||||
@ -255,30 +255,3 @@ func GetGlobalServiceDict() *ServiceDictionary {
|
|||||||
})
|
})
|
||||||
return globalServiceDict
|
return globalServiceDict
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGlobalServiceDict 设置全局服务字典实例
|
|
||||||
func SetGlobalServiceDict(dict *ServiceDictionary) {
|
|
||||||
globalServiceDict = dict
|
|
||||||
}
|
|
||||||
|
|
||||||
// 便利函数,直接使用全局实例
|
|
||||||
|
|
||||||
// GetUserDict 获取指定服务的用户字典(全局函数)
|
|
||||||
func GetUserDict(service string) []string {
|
|
||||||
return GetGlobalServiceDict().GetUserDict(service)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPasswords 获取默认密码字典(全局函数)
|
|
||||||
func GetPasswords() []string {
|
|
||||||
return GetGlobalServiceDict().GetPasswords()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetUserDict 设置指定服务的用户字典(全局函数)
|
|
||||||
func SetUserDict(service string, users []string) {
|
|
||||||
GetGlobalServiceDict().SetUserDict(service, users)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPasswords 设置密码字典(全局函数)
|
|
||||||
func SetPasswords(passwords []string) {
|
|
||||||
GetGlobalServiceDict().SetPasswords(passwords)
|
|
||||||
}
|
|
@ -38,7 +38,7 @@ func GetText(key string, args ...interface{}) string {
|
|||||||
if lang == "" {
|
if lang == "" {
|
||||||
lang = LangZH
|
lang = LangZH
|
||||||
}
|
}
|
||||||
|
|
||||||
if textMap, exists := coreMessages[key]; exists {
|
if textMap, exists := coreMessages[key]; exists {
|
||||||
if text, langExists := textMap[lang]; langExists {
|
if text, langExists := textMap[lang]; langExists {
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
@ -50,14 +50,9 @@ func GetText(key string, args ...interface{}) string {
|
|||||||
return key // 找不到时返回key
|
return key // 找不到时返回key
|
||||||
}
|
}
|
||||||
|
|
||||||
// T 简化别名
|
|
||||||
func T(key string, args ...interface{}) string {
|
|
||||||
return GetText(key, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetLanguage 设置语言(保持兼容性)
|
// SetLanguage 设置语言(保持兼容性)
|
||||||
func SetLanguage(lang string) {
|
func SetLanguage(lang string) {
|
||||||
if lang == LangZH || lang == LangEN {
|
if lang == LangZH || lang == LangEN {
|
||||||
Language = lang
|
Language = lang
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ func (f *StandardFormatter) Format(entry *LogEntry) string {
|
|||||||
elapsed := time.Since(f.startTime)
|
elapsed := time.Since(f.startTime)
|
||||||
timeStr := f.formatElapsedTime(elapsed)
|
timeStr := f.formatElapsedTime(elapsed)
|
||||||
prefix := f.getLevelPrefix(entry.Level)
|
prefix := f.getLevelPrefix(entry.Level)
|
||||||
|
|
||||||
return fmt.Sprintf("[%s] %s %s", timeStr, prefix, entry.Content)
|
return fmt.Sprintf("[%s] %s %s", timeStr, prefix, entry.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,27 +75,18 @@ type DetailedFormatter struct {
|
|||||||
includeMetadata bool
|
includeMetadata bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDetailedFormatter 创建详细格式化器
|
|
||||||
func NewDetailedFormatter(includeSource, includeMetadata bool) *DetailedFormatter {
|
|
||||||
return &DetailedFormatter{
|
|
||||||
StandardFormatter: StandardFormatter{startTime: time.Now()},
|
|
||||||
includeSource: includeSource,
|
|
||||||
includeMetadata: includeMetadata,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format 格式化日志条目(包含详细信息)
|
// Format 格式化日志条目(包含详细信息)
|
||||||
func (f *DetailedFormatter) Format(entry *LogEntry) string {
|
func (f *DetailedFormatter) Format(entry *LogEntry) string {
|
||||||
baseFormat := f.StandardFormatter.Format(entry)
|
baseFormat := f.StandardFormatter.Format(entry)
|
||||||
|
|
||||||
if f.includeSource && entry.Source != "" {
|
if f.includeSource && entry.Source != "" {
|
||||||
baseFormat += fmt.Sprintf(" [%s]", entry.Source)
|
baseFormat += fmt.Sprintf(" [%s]", entry.Source)
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.includeMetadata && len(entry.Metadata) > 0 {
|
if f.includeMetadata && len(entry.Metadata) > 0 {
|
||||||
baseFormat += fmt.Sprintf(" %v", entry.Metadata)
|
baseFormat += fmt.Sprintf(" %v", entry.Metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
return baseFormat
|
return baseFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,13 +95,6 @@ type JSONFormatter struct {
|
|||||||
startTime time.Time
|
startTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewJSONFormatter 创建JSON格式化器
|
|
||||||
func NewJSONFormatter() *JSONFormatter {
|
|
||||||
return &JSONFormatter{
|
|
||||||
startTime: time.Now(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetStartTime 设置开始时间
|
// SetStartTime 设置开始时间
|
||||||
func (f *JSONFormatter) SetStartTime(startTime time.Time) {
|
func (f *JSONFormatter) SetStartTime(startTime time.Time) {
|
||||||
f.startTime = startTime
|
f.startTime = startTime
|
||||||
@ -119,23 +103,23 @@ func (f *JSONFormatter) SetStartTime(startTime time.Time) {
|
|||||||
// Format 格式化为JSON格式
|
// Format 格式化为JSON格式
|
||||||
func (f *JSONFormatter) Format(entry *LogEntry) string {
|
func (f *JSONFormatter) Format(entry *LogEntry) string {
|
||||||
elapsed := time.Since(f.startTime)
|
elapsed := time.Since(f.startTime)
|
||||||
|
|
||||||
jsonStr := fmt.Sprintf(`{"level":"%s","time":"%s","elapsed_ms":%d,"content":"%s"`,
|
jsonStr := fmt.Sprintf(`{"level":"%s","time":"%s","elapsed_ms":%d,"content":"%s"`,
|
||||||
entry.Level,
|
entry.Level,
|
||||||
entry.Time.Format("2006-01-02T15:04:05.000Z07:00"),
|
entry.Time.Format("2006-01-02T15:04:05.000Z07:00"),
|
||||||
elapsed.Milliseconds(),
|
elapsed.Milliseconds(),
|
||||||
entry.Content)
|
entry.Content)
|
||||||
|
|
||||||
if entry.Source != "" {
|
if entry.Source != "" {
|
||||||
jsonStr += fmt.Sprintf(`,"source":"%s"`, entry.Source)
|
jsonStr += fmt.Sprintf(`,"source":"%s"`, entry.Source)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(entry.Metadata) > 0 {
|
if len(entry.Metadata) > 0 {
|
||||||
jsonStr += `,"metadata":`
|
jsonStr += `,"metadata":`
|
||||||
// 这里为简化处理,使用简单的格式
|
// 这里为简化处理,使用简单的格式
|
||||||
jsonStr += fmt.Sprintf(`%v`, entry.Metadata)
|
jsonStr += fmt.Sprintf(`%v`, entry.Metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonStr += "}"
|
jsonStr += "}"
|
||||||
return jsonStr
|
return jsonStr
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,14 @@ import (
|
|||||||
|
|
||||||
// Logger 日志管理器
|
// Logger 日志管理器
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
config *LoggerConfig
|
config *LoggerConfig
|
||||||
formatter LogFormatter
|
formatter LogFormatter
|
||||||
handlers []LogHandler
|
handlers []LogHandler
|
||||||
scanStatus *ScanStatus
|
scanStatus *ScanStatus
|
||||||
progressBar ProgressDisplay
|
progressBar ProgressDisplay
|
||||||
outputMutex *sync.Mutex
|
outputMutex *sync.Mutex
|
||||||
initialized bool
|
initialized bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLogger 创建新的日志管理器
|
// NewLogger 创建新的日志管理器
|
||||||
@ -223,7 +223,7 @@ type ConsoleHandler struct {
|
|||||||
func NewConsoleHandler(config *LoggerConfig) *ConsoleHandler {
|
func NewConsoleHandler(config *LoggerConfig) *ConsoleHandler {
|
||||||
formatter := NewStandardFormatter()
|
formatter := NewStandardFormatter()
|
||||||
formatter.SetStartTime(config.StartTime)
|
formatter.SetStartTime(config.StartTime)
|
||||||
|
|
||||||
return &ConsoleHandler{
|
return &ConsoleHandler{
|
||||||
config: config,
|
config: config,
|
||||||
formatter: formatter,
|
formatter: formatter,
|
||||||
@ -274,25 +274,6 @@ func (h *ConsoleHandler) IsEnabled() bool {
|
|||||||
return h.enabled
|
return h.enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全局日志管理器实例
|
|
||||||
var (
|
|
||||||
globalLogger *Logger
|
|
||||||
initOnce sync.Once
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetGlobalLogger 获取全局日志管理器
|
|
||||||
func GetGlobalLogger() *Logger {
|
|
||||||
initOnce.Do(func() {
|
|
||||||
globalLogger = NewLogger(DefaultLoggerConfig())
|
|
||||||
})
|
|
||||||
return globalLogger
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGlobalLogger 设置全局日志管理器
|
|
||||||
func SetGlobalLogger(logger *Logger) {
|
|
||||||
globalLogger = logger
|
|
||||||
}
|
|
||||||
|
|
||||||
// 错误检查函数(保持原有逻辑)
|
// 错误检查函数(保持原有逻辑)
|
||||||
func CheckErrs(err error) error {
|
func CheckErrs(err error) error {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -321,4 +302,4 @@ func CheckErrs(err error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -10,17 +10,17 @@ import (
|
|||||||
|
|
||||||
// Manager 输出管理器
|
// Manager 输出管理器
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
config *ManagerConfig
|
config *ManagerConfig
|
||||||
writer OutputWriter
|
writer OutputWriter
|
||||||
reader OutputReader
|
reader OutputReader
|
||||||
statistics *Statistics
|
statistics *Statistics
|
||||||
buffer []*ScanResult
|
buffer []*ScanResult
|
||||||
bufferMutex sync.Mutex
|
bufferMutex sync.Mutex
|
||||||
flushTicker *time.Ticker
|
flushTicker *time.Ticker
|
||||||
stopChan chan struct{}
|
stopChan chan struct{}
|
||||||
initialized bool
|
initialized bool
|
||||||
closed bool
|
closed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManager 创建新的输出管理器
|
// NewManager 创建新的输出管理器
|
||||||
@ -56,7 +56,7 @@ func NewManager(config *ManagerConfig) (*Manager, error) {
|
|||||||
// 如果启用缓冲,初始化缓冲区
|
// 如果启用缓冲,初始化缓冲区
|
||||||
if config.EnableBuffer {
|
if config.EnableBuffer {
|
||||||
manager.buffer = make([]*ScanResult, 0, config.BufferSize)
|
manager.buffer = make([]*ScanResult, 0, config.BufferSize)
|
||||||
|
|
||||||
// 如果启用自动刷新,启动定时器
|
// 如果启用自动刷新,启动定时器
|
||||||
if config.AutoFlush {
|
if config.AutoFlush {
|
||||||
manager.startAutoFlush()
|
manager.startAutoFlush()
|
||||||
@ -299,7 +299,7 @@ func (m *Manager) IsClosed() bool {
|
|||||||
func (m *Manager) GetConfig() *ManagerConfig {
|
func (m *Manager) GetConfig() *ManagerConfig {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
|
|
||||||
// 返回配置副本
|
// 返回配置副本
|
||||||
config := *m.config
|
config := *m.config
|
||||||
return &config
|
return &config
|
||||||
@ -354,26 +354,9 @@ func (m *Manager) UpdateConfig(updates map[string]interface{}) error {
|
|||||||
// 全局输出管理器实例
|
// 全局输出管理器实例
|
||||||
var (
|
var (
|
||||||
globalManager *Manager
|
globalManager *Manager
|
||||||
managerOnce sync.Once
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetGlobalManager 获取全局输出管理器
|
|
||||||
func GetGlobalManager() *Manager {
|
|
||||||
return globalManager
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetGlobalManager 设置全局输出管理器
|
// SetGlobalManager 设置全局输出管理器
|
||||||
func SetGlobalManager(manager *Manager) {
|
func SetGlobalManager(manager *Manager) {
|
||||||
globalManager = manager
|
globalManager = manager
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitGlobalManager 初始化全局输出管理器
|
|
||||||
func InitGlobalManager(config *ManagerConfig) error {
|
|
||||||
manager, err := NewManager(config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
SetGlobalManager(manager)
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -22,8 +22,6 @@ const (
|
|||||||
TypePort ResultType = "PORT" // 端口开放
|
TypePort ResultType = "PORT" // 端口开放
|
||||||
TypeService ResultType = "SERVICE" // 服务识别
|
TypeService ResultType = "SERVICE" // 服务识别
|
||||||
TypeVuln ResultType = "VULN" // 漏洞发现
|
TypeVuln ResultType = "VULN" // 漏洞发现
|
||||||
TypeInfo ResultType = "INFO" // 信息收集
|
|
||||||
TypeBrute ResultType = "BRUTE" // 爆破结果
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ScanResult 扫描结果结构
|
// ScanResult 扫描结果结构
|
||||||
@ -53,11 +51,11 @@ type OutputReader interface {
|
|||||||
|
|
||||||
// ResultFilter 结果过滤器
|
// ResultFilter 结果过滤器
|
||||||
type ResultFilter struct {
|
type ResultFilter struct {
|
||||||
Types []ResultType `json:"types"` // 过滤的结果类型
|
Types []ResultType `json:"types"` // 过滤的结果类型
|
||||||
Targets []string `json:"targets"` // 过滤的目标
|
Targets []string `json:"targets"` // 过滤的目标
|
||||||
TimeRange *TimeRange `json:"time_range"` // 时间范围
|
TimeRange *TimeRange `json:"time_range"` // 时间范围
|
||||||
Limit int `json:"limit"` // 限制数量
|
Limit int `json:"limit"` // 限制数量
|
||||||
Offset int `json:"offset"` // 偏移量
|
Offset int `json:"offset"` // 偏移量
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimeRange 时间范围
|
// TimeRange 时间范围
|
||||||
@ -68,11 +66,11 @@ type TimeRange struct {
|
|||||||
|
|
||||||
// ManagerConfig 输出管理器配置
|
// ManagerConfig 输出管理器配置
|
||||||
type ManagerConfig struct {
|
type ManagerConfig struct {
|
||||||
OutputPath string `json:"output_path"` // 输出路径
|
OutputPath string `json:"output_path"` // 输出路径
|
||||||
Format OutputFormat `json:"format"` // 输出格式
|
Format OutputFormat `json:"format"` // 输出格式
|
||||||
EnableBuffer bool `json:"enable_buffer"` // 是否启用缓冲
|
EnableBuffer bool `json:"enable_buffer"` // 是否启用缓冲
|
||||||
BufferSize int `json:"buffer_size"` // 缓冲区大小
|
BufferSize int `json:"buffer_size"` // 缓冲区大小
|
||||||
AutoFlush bool `json:"auto_flush"` // 是否自动刷新
|
AutoFlush bool `json:"auto_flush"` // 是否自动刷新
|
||||||
FlushInterval time.Duration `json:"flush_interval"` // 刷新间隔
|
FlushInterval time.Duration `json:"flush_interval"` // 刷新间隔
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,10 +89,10 @@ func DefaultManagerConfig(outputPath string, format OutputFormat) *ManagerConfig
|
|||||||
// Statistics 输出统计信息
|
// Statistics 输出统计信息
|
||||||
type Statistics struct {
|
type Statistics struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
TotalResults int64 `json:"total_results"` // 总结果数
|
TotalResults int64 `json:"total_results"` // 总结果数
|
||||||
TypeCounts map[ResultType]int64 `json:"type_counts"` // 各类型计数
|
TypeCounts map[ResultType]int64 `json:"type_counts"` // 各类型计数
|
||||||
StartTime time.Time `json:"start_time"` // 开始时间
|
StartTime time.Time `json:"start_time"` // 开始时间
|
||||||
LastUpdate time.Time `json:"last_update"` // 最后更新时间
|
LastUpdate time.Time `json:"last_update"` // 最后更新时间
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStatistics 创建新的统计信息
|
// NewStatistics 创建新的统计信息
|
||||||
@ -126,7 +124,7 @@ func (s *Statistics) GetTotalResults() int64 {
|
|||||||
func (s *Statistics) GetTypeCounts() map[ResultType]int64 {
|
func (s *Statistics) GetTypeCounts() map[ResultType]int64 {
|
||||||
s.mu.RLock()
|
s.mu.RLock()
|
||||||
defer s.mu.RUnlock()
|
defer s.mu.RUnlock()
|
||||||
|
|
||||||
// 返回副本以避免并发问题
|
// 返回副本以避免并发问题
|
||||||
counts := make(map[ResultType]int64)
|
counts := make(map[ResultType]int64)
|
||||||
for k, v := range s.TypeCounts {
|
for k, v := range s.TypeCounts {
|
||||||
@ -150,4 +148,4 @@ func (s *Statistics) Reset() {
|
|||||||
s.TypeCounts = make(map[ResultType]int64)
|
s.TypeCounts = make(map[ResultType]int64)
|
||||||
s.StartTime = time.Now()
|
s.StartTime = time.Now()
|
||||||
s.LastUpdate = time.Now()
|
s.LastUpdate = time.Now()
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,13 @@ type ParsedConfig struct {
|
|||||||
|
|
||||||
// TargetConfig 目标配置
|
// TargetConfig 目标配置
|
||||||
type TargetConfig struct {
|
type TargetConfig struct {
|
||||||
Hosts []string `json:"hosts"`
|
Hosts []string `json:"hosts"`
|
||||||
URLs []string `json:"urls"`
|
URLs []string `json:"urls"`
|
||||||
Ports []int `json:"ports"`
|
Ports []int `json:"ports"`
|
||||||
ExcludePorts []int `json:"exclude_ports"`
|
ExcludePorts []int `json:"exclude_ports"`
|
||||||
HostPorts []string `json:"host_ports"`
|
HostPorts []string `json:"host_ports"`
|
||||||
LocalMode bool `json:"local_mode"`
|
LocalMode bool `json:"local_mode"`
|
||||||
Statistics *TargetStatistics `json:"statistics,omitempty"`
|
Statistics *TargetStatistics `json:"statistics,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TargetStatistics 目标解析统计
|
// TargetStatistics 目标解析统计
|
||||||
@ -36,36 +36,36 @@ type TargetStatistics struct {
|
|||||||
|
|
||||||
// CredentialConfig 认证配置
|
// CredentialConfig 认证配置
|
||||||
type CredentialConfig struct {
|
type CredentialConfig struct {
|
||||||
Usernames []string `json:"usernames"`
|
Usernames []string `json:"usernames"`
|
||||||
Passwords []string `json:"passwords"`
|
Passwords []string `json:"passwords"`
|
||||||
HashValues []string `json:"hash_values"`
|
HashValues []string `json:"hash_values"`
|
||||||
HashBytes [][]byte `json:"hash_bytes,omitempty"`
|
HashBytes [][]byte `json:"hash_bytes,omitempty"`
|
||||||
SshKeyPath string `json:"ssh_key_path"`
|
SshKeyPath string `json:"ssh_key_path"`
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
Statistics *CredentialStats `json:"statistics,omitempty"`
|
Statistics *CredentialStats `json:"statistics,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CredentialStats 认证配置统计
|
// CredentialStats 认证配置统计
|
||||||
type CredentialStats struct {
|
type CredentialStats struct {
|
||||||
TotalUsernames int `json:"total_usernames"`
|
TotalUsernames int `json:"total_usernames"`
|
||||||
TotalPasswords int `json:"total_passwords"`
|
TotalPasswords int `json:"total_passwords"`
|
||||||
TotalHashes int `json:"total_hashes"`
|
TotalHashes int `json:"total_hashes"`
|
||||||
UniqueUsernames int `json:"unique_usernames"`
|
UniqueUsernames int `json:"unique_usernames"`
|
||||||
UniquePasswords int `json:"unique_passwords"`
|
UniquePasswords int `json:"unique_passwords"`
|
||||||
ValidHashes int `json:"valid_hashes"`
|
ValidHashes int `json:"valid_hashes"`
|
||||||
InvalidHashes int `json:"invalid_hashes"`
|
InvalidHashes int `json:"invalid_hashes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkConfig 网络配置
|
// NetworkConfig 网络配置
|
||||||
type NetworkConfig struct {
|
type NetworkConfig struct {
|
||||||
HttpProxy string `json:"http_proxy"`
|
HttpProxy string `json:"http_proxy"`
|
||||||
Socks5Proxy string `json:"socks5_proxy"`
|
Socks5Proxy string `json:"socks5_proxy"`
|
||||||
Timeout time.Duration `json:"timeout"`
|
Timeout time.Duration `json:"timeout"`
|
||||||
WebTimeout time.Duration `json:"web_timeout"`
|
WebTimeout time.Duration `json:"web_timeout"`
|
||||||
DisablePing bool `json:"disable_ping"`
|
DisablePing bool `json:"disable_ping"`
|
||||||
EnableDNSLog bool `json:"enable_dns_log"`
|
EnableDNSLog bool `json:"enable_dns_log"`
|
||||||
UserAgent string `json:"user_agent"`
|
UserAgent string `json:"user_agent"`
|
||||||
Cookie string `json:"cookie"`
|
Cookie string `json:"cookie"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidationConfig 验证配置
|
// ValidationConfig 验证配置
|
||||||
@ -87,27 +87,19 @@ type ParseResult struct {
|
|||||||
|
|
||||||
// 预定义错误类型
|
// 预定义错误类型
|
||||||
var (
|
var (
|
||||||
ErrEmptyInput = errors.New("输入参数为空")
|
ErrEmptyInput = errors.New("输入参数为空")
|
||||||
ErrInvalidFormat = errors.New("格式无效")
|
|
||||||
ErrFileNotFound = errors.New("文件未找到")
|
|
||||||
ErrConflictingParams = errors.New("参数冲突")
|
|
||||||
ErrInvalidProxy = errors.New("代理配置无效")
|
|
||||||
ErrInvalidHash = errors.New("哈希值无效")
|
|
||||||
ErrInvalidPort = errors.New("端口号无效")
|
|
||||||
ErrInvalidIP = errors.New("IP地址无效")
|
|
||||||
ErrInvalidURL = errors.New("URL格式无效")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParserOptions 解析器选项
|
// ParserOptions 解析器选项
|
||||||
type ParserOptions struct {
|
type ParserOptions struct {
|
||||||
EnableConcurrency bool // 启用并发解析
|
EnableConcurrency bool // 启用并发解析
|
||||||
MaxWorkers int // 最大工作协程数
|
MaxWorkers int // 最大工作协程数
|
||||||
Timeout time.Duration // 解析超时时间
|
Timeout time.Duration // 解析超时时间
|
||||||
EnableValidation bool // 启用详细验证
|
EnableValidation bool // 启用详细验证
|
||||||
EnableStatistics bool // 启用统计信息
|
EnableStatistics bool // 启用统计信息
|
||||||
IgnoreErrors bool // 忽略非致命错误
|
IgnoreErrors bool // 忽略非致命错误
|
||||||
FileMaxSize int64 // 文件最大大小限制
|
FileMaxSize int64 // 文件最大大小限制
|
||||||
MaxTargets int // 最大目标数量限制
|
MaxTargets int // 最大目标数量限制
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultParserOptions 返回默认解析器选项
|
// DefaultParserOptions 返回默认解析器选项
|
||||||
@ -120,7 +112,7 @@ func DefaultParserOptions() *ParserOptions {
|
|||||||
EnableStatistics: true,
|
EnableStatistics: true,
|
||||||
IgnoreErrors: false,
|
IgnoreErrors: false,
|
||||||
FileMaxSize: 100 * 1024 * 1024, // 100MB
|
FileMaxSize: 100 * 1024 * 1024, // 100MB
|
||||||
MaxTargets: 10000, // 10K targets
|
MaxTargets: 10000, // 10K targets
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,4 +158,4 @@ func NewParseError(errType, message, source string, line int, original error) *P
|
|||||||
Line: line,
|
Line: line,
|
||||||
Original: original,
|
Original: original,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user