mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-22 03:10:42 +08:00
use config proxy state for credential prechecks
This commit is contained in:
@@ -112,6 +112,7 @@ type ConcurrentTestConfig struct {
|
|||||||
RetryDelay time.Duration // 重试延迟,默认 1s
|
RetryDelay time.Duration // 重试延迟,默认 1s
|
||||||
MaxConsecutiveNetErrors int // 连续网络错误阈值,超过则认为目标不可达,默认 5
|
MaxConsecutiveNetErrors int // 连续网络错误阈值,超过则认为目标不可达,默认 5
|
||||||
TargetAddr string // 目标地址 host:port,用于 TCP 预检(可选)
|
TargetAddr string // 目标地址 host:port,用于 TCP 预检(可选)
|
||||||
|
UseProxy bool // 代理模式下跳过直连 TCP 预检
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultConcurrentTestConfig 默认配置
|
// DefaultConcurrentTestConfig 默认配置
|
||||||
@@ -125,6 +126,7 @@ func DefaultConcurrentTestConfig(config *common.Config) ConcurrentTestConfig {
|
|||||||
MaxRetries: 3,
|
MaxRetries: 3,
|
||||||
RetryDelay: time.Second,
|
RetryDelay: time.Second,
|
||||||
MaxConsecutiveNetErrors: 5,
|
MaxConsecutiveNetErrors: 5,
|
||||||
|
UseProxy: config.Network.Socks5Proxy != "" || config.Network.HTTPProxy != "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +156,7 @@ func TestCredentialsConcurrently(
|
|||||||
|
|
||||||
// TCP 预检:快速验证目标可达,避免对不可达目标浪费全部凭据尝试
|
// TCP 预检:快速验证目标可达,避免对不可达目标浪费全部凭据尝试
|
||||||
// 代理模式下跳过:net.DialTimeout 直连无法到达代理后的内网目标
|
// 代理模式下跳过:net.DialTimeout 直连无法到达代理后的内网目标
|
||||||
if testConfig.TargetAddr != "" && !common.IsProxyEnabled() {
|
if testConfig.TargetAddr != "" && !testConfig.UseProxy {
|
||||||
preConn, err := net.DialTimeout("tcp", testConfig.TargetAddr, 3*time.Second)
|
preConn, err := net.DialTimeout("tcp", testConfig.TargetAddr, 3*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &ScanResult{
|
return &ScanResult{
|
||||||
|
|||||||
@@ -268,6 +268,33 @@ func TestTestCredentialsConcurrently_EmptyCredentials(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTestCredentialsConcurrently_ProxySkipsDirectPrecheck(t *testing.T) {
|
||||||
|
var calls atomic.Int32
|
||||||
|
authFn := func(ctx context.Context, cred Credential) *AuthResult {
|
||||||
|
calls.Add(1)
|
||||||
|
return &AuthResult{
|
||||||
|
Success: true,
|
||||||
|
Conn: &mockConn{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config := ConcurrentTestConfig{
|
||||||
|
Concurrency: 1,
|
||||||
|
MaxRetries: 1,
|
||||||
|
RetryDelay: time.Millisecond,
|
||||||
|
TargetAddr: "127.0.0.1:1",
|
||||||
|
UseProxy: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
result := TestCredentialsConcurrently(context.Background(), []Credential{{Username: "u", Password: "p"}}, authFn, "test", config)
|
||||||
|
if !result.Success {
|
||||||
|
t.Fatalf("proxy mode should skip direct precheck: %v", result.Error)
|
||||||
|
}
|
||||||
|
if calls.Load() == 0 {
|
||||||
|
t.Fatal("auth function was not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestTestCredentialsConcurrently_ContextCancel 测试context取消
|
// TestTestCredentialsConcurrently_ContextCancel 测试context取消
|
||||||
func TestTestCredentialsConcurrently_ContextCancel(t *testing.T) {
|
func TestTestCredentialsConcurrently_ContextCancel(t *testing.T) {
|
||||||
credentials := make([]Credential, 100)
|
credentials := make([]Credential, 100)
|
||||||
@@ -451,4 +478,3 @@ func TestRetryLogic_AuthErrorNoRetry(t *testing.T) {
|
|||||||
|
|
||||||
// 确保 mockConn 实现 io.Closer 接口
|
// 确保 mockConn 实现 io.Closer 接口
|
||||||
var _ io.Closer = (*mockConn)(nil)
|
var _ io.Closer = (*mockConn)(nil)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user