fix: set conn deadline in smtp testAnonymousAccess/testOpenRelay to avoid hang on silent servers

testAnonymousAccess and testOpenRelay dial the target and immediately
hand the connection to smtp.NewClient without setting any deadline.
smtp.NewClient reads the 220 greeting as its first operation, so a
server that accepts TCP but never sends data (honeypot/tarpit) blocks
the goroutine forever. The outer select waits on resultChan or
ctx.Done(); with the default -gt 0 the context has no deadline, so
Scan never returns and RunScan's wg.Wait() freezes the whole process.

Set the same ModuleTimeout deadline used by the other functions in
this file (doSMTPAuth, testVRFYCommand, testEXPNCommand, getServerInfo).

Verified against a live accept-but-silent SMTP endpoint:
- unpatched: process hangs (31 goroutines, stack at smtp.go:276)
- patched: full plugin chain completes in ~92s, no regression on
  normally-responding servers (detection output identical)
This commit is contained in:
NOPTrace
2026-09-17 09:24:05 +08:00
parent 95cc12e753
commit 6bb8ccd490
+6
View File
@@ -243,6 +243,9 @@ func (p *SMTPPlugin) testAnonymousAccess(ctx context.Context, info *common.HostI
} }
defer func() { _ = conn.Close() }() defer func() { _ = conn.Close() }()
// 修复: 设置读写超时, 防止对只accept不发送banner的服务器(tarpit)永久阻塞
_ = conn.SetDeadline(time.Now().Add(session.Config.ModuleTimeout()))
client, err := smtp.NewClient(conn, info.Host) client, err := smtp.NewClient(conn, info.Host)
if err != nil { if err != nil {
resultChan <- nil resultChan <- nil
@@ -295,6 +298,9 @@ func (p *SMTPPlugin) testOpenRelay(ctx context.Context, info *common.HostInfo, s
} }
defer func() { _ = conn.Close() }() defer func() { _ = conn.Close() }()
// 修复: 设置读写超时, 防止对只accept不发送banner的服务器(tarpit)永久阻塞
_ = conn.SetDeadline(time.Now().Add(session.Config.ModuleTimeout()))
client, err := smtp.NewClient(conn, info.Host) client, err := smtp.NewClient(conn, info.Host)
if err != nil { if err != nil {
resultChan <- nil resultChan <- nil