From 51492f802c478d0257e78b0e07f0edd0750fc1c8 Mon Sep 17 00:00:00 2001 From: artin Date: Wed, 3 Dec 2025 03:16:48 +0800 Subject: [PATCH] ALIDNS: Add TXT record validation --- pkg/rejectif/txt.go | 23 +++++++++++++++++++++++ providers/alidns/api.go | 7 +------ providers/alidns/auditrecords.go | 9 ++++++--- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/pkg/rejectif/txt.go b/pkg/rejectif/txt.go index 7f3f2ef31..bab0a6677 100644 --- a/pkg/rejectif/txt.go +++ b/pkg/rejectif/txt.go @@ -18,6 +18,29 @@ func TxtHasBackslash(rc *models.RecordConfig) error { return nil } +// TxtHasUnpairedBackslash audits TXT records for strings that contain an odd number of consecutive backslashes. +// Some providers strip single backslashes or convert odd consecutive backslashes to even. +// e.g., "1back\slash" -> "1backslash", "3back\\\slash" -> "3back\\slash" +func TxtHasUnpairedBackslash(rc *models.RecordConfig) error { + txt := rc.GetTargetTXTJoined() + i := 0 + for i < len(txt) { + if txt[i] == '\\' { + count := 0 + for i < len(txt) && txt[i] == '\\' { + count++ + i++ + } + if count%2 == 1 { + return errors.New("txtstring contains unpaired backslash (odd count)") + } + } else { + i++ + } + } + return nil +} + // TxtHasBackticks audits TXT records for strings that contain backticks. func TxtHasBackticks(rc *models.RecordConfig) error { if strings.Contains(rc.GetTargetTXTJoined(), "`") { diff --git a/providers/alidns/api.go b/providers/alidns/api.go index aaf1e256a..51a1abff2 100644 --- a/providers/alidns/api.go +++ b/providers/alidns/api.go @@ -51,15 +51,10 @@ func (a *aliDnsDsp) createRecordset(records []*models.RecordConfig, domainName s req.Priority = requests.Integer(fmt.Sprintf("%d", recordToNativePriority(r))) } - fmt.Printf("DEBUG createRecordset: domain=%s, RR=%s, Type=%s, Value=%s, TTL=%s\n", - req.DomainName, req.RR, req.Type, req.Value, req.TTL) - - resp, err := a.client.AddDomainRecord(req) + _, err := a.client.AddDomainRecord(req) if err != nil { - fmt.Printf("DEBUG createRecordset error: %v\n", err) return err } - fmt.Printf("DEBUG createRecordset success: RecordId=%s\n", resp.RecordId) } return nil } diff --git a/providers/alidns/auditrecords.go b/providers/alidns/auditrecords.go index 1790f79d3..60d79e54b 100644 --- a/providers/alidns/auditrecords.go +++ b/providers/alidns/auditrecords.go @@ -11,8 +11,11 @@ import ( func AuditRecords(records []*models.RecordConfig) []error { a := rejectif.Auditor{} - a.Add("MX", rejectif.MxNull) // Last verified at 2025-12-03 - a.Add("TXT", rejectif.TxtIsEmpty) // Last verified at 2025-12-03 - a.Add("TXT", rejectif.TxtLongerThan(512)) // Last verified at 2025-12-03: 511 bytes OK, 764 bytes failed + a.Add("MX", rejectif.MxNull) // Last verified at 2025-12-03 + a.Add("TXT", rejectif.TxtIsEmpty) // Last verified at 2025-12-03 + a.Add("TXT", rejectif.TxtLongerThan(512)) // Last verified at 2025-12-03: 511 bytes OK, 764 bytes failed + a.Add("TXT", rejectif.TxtHasDoubleQuotes) // Last verified at 2025-12-03: Alibaba strips quotes + a.Add("TXT", rejectif.TxtHasTrailingSpace) // Last verified at 2025-12-03: Alibaba strips trailing spaces + a.Add("TXT", rejectif.TxtHasUnpairedBackslash) // Last verified at 2025-12-03: Alibaba mishandles odd backslashes return a.Audit(records) }