diff --git a/go.mod b/go.mod index dcc4ced70..53d6b194c 100644 --- a/go.mod +++ b/go.mod @@ -93,6 +93,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deepmap/oapi-codegen v1.9.1 // indirect + github.com/facebook/dns/dnsrocks v0.0.0-20231026153830-f5723c53d019 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/go-jose/go-jose/v3 v3.0.0 // indirect github.com/go-test/deep v1.0.3 // indirect diff --git a/go.sum b/go.sum index a90b47734..f5c2662ee 100644 --- a/go.sum +++ b/go.sum @@ -109,6 +109,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/exoscale/egoscale v0.90.2 h1:oGSJy5Dxbcn5m5F0/DcnU4WXJg+2j3g+UgEu4yyKG9M= github.com/exoscale/egoscale v0.90.2/go.mod h1:NDhQbdGNKwnLVC2YGTB6ds9WIPw+V5ckvEEV8ho7pFE= +github.com/facebook/dns/dnsrocks v0.0.0-20231026153830-f5723c53d019 h1:E5EK2U44s+IN0XyfROZbBgXcATpaWplY4USE87HKPDI= +github.com/facebook/dns/dnsrocks v0.0.0-20231026153830-f5723c53d019/go.mod h1:SaniBA3PvQwaMy8tglIAmz+hoKIwfROpxoEAnfJe8L0= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= diff --git a/integrationTest/integration_test.go b/integrationTest/integration_test.go index a21e5c037..8bc59cf27 100644 --- a/integrationTest/integration_test.go +++ b/integrationTest/integration_test.go @@ -1074,20 +1074,24 @@ func makeTests(t *testing.T) []*TestGroup { // update the AuditRecords(). // Commented this one out. Nobody supports this or needs it. - //tc("a 0-byte TXT", txt("foo0", "")), + tc("a 0-byte TXT", txt("foo0", "")), + tc("a 254-byte TXT", txt("foo254", strings.Repeat("B", 254))), tc("a 255-byte TXT", txt("foo255", strings.Repeat("C", 255))), tc("a 256-byte TXT", txt("foo256", strings.Repeat("D", 256))), - tc("a 512-byte TXT", txt("foo512", strings.Repeat("C", 512))), - tc("a 513-byte TXT", txt("foo513", strings.Repeat("D", 513))), + tc("a 510-byte TXT", txt("foo510", strings.Repeat("E", 510))), + tc("a 511-byte TXT", txt("foo511", strings.Repeat("F", 511))), + tc("a 765-byte TXT", txt("foo765", strings.Repeat("G", 765))), + tc("a 766-byte TXT", txt("foo766", strings.Repeat("H", 766))), tc("TXT with 1 single-quote", txt("foosq", "quo'te")), tc("TXT with 1 backtick", txt("foobt", "blah`blah")), tc("TXT with 1 double-quotes", txt("foodq", `quo"te`)), tc("TXT with 2 double-quotes", txt("foodqs", `q"uo"te`)), + tc("TXT with 1 backslash", txt("fooosbs", `back\slash`)), - tc("a TXT with interior ws", txt("foosp", "with spaces")), - tc("TXT with ws at end", txt("foows1", "with space at end ")), + tc("TXT interior ws", txt("foosp", "with spaces")), + tc("TXT trailing ws", txt("foows1", "with space at end ")), //tc("Create a TXT/SPF", txt("foo", "v=spf1 ip4:99.99.99.99 -all")), // This was added because Vultr syntax-checks TXT records with SPF contents. diff --git a/pkg/rejectif/txt.go b/pkg/rejectif/txt.go index 184d3e2ce..ba0fbec88 100644 --- a/pkg/rejectif/txt.go +++ b/pkg/rejectif/txt.go @@ -50,8 +50,8 @@ func TxtHasSegmentLen256orLonger(rc *models.RecordConfig) error { return nil } -// TxtHasMultipleSegments audits TXT records for multiple strings -func TxtHasMultipleSegments(rc *models.RecordConfig) error { +// TxtLongerThan255 audits TXT records for multiple strings +func TxtLongerThan255(rc *models.RecordConfig) error { if len(rc.GetTargetField()) > 255 { return fmt.Errorf("multiple strings in one txt") } diff --git a/providers/cloudflare/auditrecords.go b/providers/cloudflare/auditrecords.go index 71a66a06e..03be807fa 100644 --- a/providers/cloudflare/auditrecords.go +++ b/providers/cloudflare/auditrecords.go @@ -11,7 +11,7 @@ import ( func AuditRecords(records []*models.RecordConfig) []error { a := rejectif.Auditor{} - a.Add("TXT", rejectif.TxtHasMultipleSegments) // Last verified 2022-06-18 + a.Add("TXT", rejectif.TxtLongerThan255) // Last verified 2022-06-18 a.Add("TXT", rejectif.TxtHasTrailingSpace) // Last verified 2022-06-18 diff --git a/providers/cloudns/auditrecords.go b/providers/cloudns/auditrecords.go index 20d7b1d1d..1987dd669 100644 --- a/providers/cloudns/auditrecords.go +++ b/providers/cloudns/auditrecords.go @@ -19,7 +19,7 @@ func AuditRecords(records []*models.RecordConfig) []error { a.Add("TXT", rejectif.TxtHasDoubleQuotes) // Last verified 2021-03-01 - a.Add("TXT", rejectif.TxtHasMultipleSegments) // Last verified 2021-03-01 + a.Add("TXT", rejectif.TxtLongerThan255) // Last verified 2021-03-01 a.Add("SRV", rejectif.SrvHasNullTarget) // Last verified 2023-03-30 diff --git a/providers/cscglobal/auditrecords.go b/providers/cscglobal/auditrecords.go index 1ee9faf8c..66d8d5edf 100644 --- a/providers/cscglobal/auditrecords.go +++ b/providers/cscglobal/auditrecords.go @@ -17,7 +17,7 @@ func AuditRecords(records []*models.RecordConfig) []error { a.Add("TXT", rejectif.TxtHasDoubleQuotes) // Last verified 2022-08-08 - a.Add("TXT", rejectif.TxtHasMultipleSegments) // Last verified 2022-06-10 + a.Add("TXT", rejectif.TxtLongerThan255) // Last verified 2022-06-10 a.Add("TXT", rejectif.TxtHasTrailingSpace) // Last verified 2022-06-10 diff --git a/providers/dnsimple/auditrecords.go b/providers/dnsimple/auditrecords.go index 0354a63eb..3e8df5b63 100644 --- a/providers/dnsimple/auditrecords.go +++ b/providers/dnsimple/auditrecords.go @@ -13,7 +13,7 @@ func AuditRecords(records []*models.RecordConfig) []error { a.Add("MX", rejectif.MxNull) // Last verified 2023-03 - a.Add("TXT", rejectif.TxtHasMultipleSegments) // Last verified 2023-03 + a.Add("TXT", rejectif.TxtLongerThan255) // Last verified 2023-03 a.Add("TXT", rejectif.TxtHasTrailingSpace) // Last verified 2023-03 diff --git a/providers/msdns/auditrecords.go b/providers/msdns/auditrecords.go index f031369f6..d753677c2 100644 --- a/providers/msdns/auditrecords.go +++ b/providers/msdns/auditrecords.go @@ -19,7 +19,7 @@ func AuditRecords(records []*models.RecordConfig) []error { a.Add("TXT", rejectif.TxtHasDoubleQuotes) // Last verified 2023-02-02 - a.Add("TXT", rejectif.TxtHasMultipleSegments) // Last verified 2023-02-02 + a.Add("TXT", rejectif.TxtLongerThan255) // Last verified 2023-02-02 a.Add("TXT", rejectif.TxtHasSegmentLen256orLonger) // Last verified 2023-02-02 @@ -29,7 +29,5 @@ func AuditRecords(records []*models.RecordConfig) []error { a.Add("TXT", rejectif.TxtIsExactlyLen255) // Last verified 2023-02-02 - a.Add("TXT", rejectif.TxtIsExactlyLen255) // Last verified 2023-02-02 - return a.Audit(records) } diff --git a/providers/ns1/auditrecords.go b/providers/ns1/auditrecords.go index d30fc8610..3d886a767 100644 --- a/providers/ns1/auditrecords.go +++ b/providers/ns1/auditrecords.go @@ -11,7 +11,7 @@ import ( func AuditRecords(records []*models.RecordConfig) []error { a := rejectif.Auditor{} - a.Add("TXT", rejectif.TxtHasMultipleSegments) + a.Add("TXT", rejectif.TxtLongerThan255) return a.Audit(records) } diff --git a/providers/route53/auditrecords.go b/providers/route53/auditrecords.go index 76534b99a..37fdf402b 100644 --- a/providers/route53/auditrecords.go +++ b/providers/route53/auditrecords.go @@ -14,6 +14,7 @@ func AuditRecords(records []*models.RecordConfig) []error { a := rejectif.Auditor{} a.Add("R53_ALIAS", rejectifTargetEqualsLabel) // Last verified 2023-03-01 + a.Add("TXT", rejectif.TxtIsEmpty) // Last verified 2023-10-28 return a.Audit(records) } diff --git a/providers/route53/route53Provider.go b/providers/route53/route53Provider.go index 2c4b2cd39..ab0dffc0c 100644 --- a/providers/route53/route53Provider.go +++ b/providers/route53/route53Provider.go @@ -14,6 +14,7 @@ import ( "github.com/StackExchange/dnscontrol/v4/models" "github.com/StackExchange/dnscontrol/v4/pkg/diff2" "github.com/StackExchange/dnscontrol/v4/pkg/printer" + "github.com/StackExchange/dnscontrol/v4/pkg/txtutil" "github.com/StackExchange/dnscontrol/v4/providers" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" @@ -340,10 +341,22 @@ func (r *route53Provider) GetZoneRecordsCorrections(dc *models.DomainConfig, exi } for _, r := range inst.New { - rr := r53Types.ResourceRecord{ - Value: aws.String(r.GetTargetCombined()), + + var rr r53Types.ResourceRecord + if instType == "TXT" { + //printer.Printf("DEBUG: txt=%q\n", r.GetTargetField()) + t := txtutil.RFC1035ChunkedAndQuoted(r.GetTargetField()) + //printer.Printf("DEBUG: t=%s\n", t) + rr = r53Types.ResourceRecord{ + Value: aws.String(t), + } + } else { + rr = r53Types.ResourceRecord{ + Value: aws.String(r.GetTargetCombined()), + } } rrset.ResourceRecords = append(rrset.ResourceRecords, rr) + i := int64(r.TTL) rrset.TTL = &i } diff --git a/providers/rwth/auditrecords.go b/providers/rwth/auditrecords.go index fee9c390c..a592cfb73 100644 --- a/providers/rwth/auditrecords.go +++ b/providers/rwth/auditrecords.go @@ -11,7 +11,7 @@ import ( func AuditRecords(records []*models.RecordConfig) []error { a := rejectif.Auditor{} - a.Add("TXT", rejectif.TxtHasMultipleSegments) + a.Add("TXT", rejectif.TxtLongerThan255) a.Add("TXT", rejectif.TxtHasTrailingSpace) diff --git a/providers/vultr/auditrecords.go b/providers/vultr/auditrecords.go index e6aed4759..669a3029c 100644 --- a/providers/vultr/auditrecords.go +++ b/providers/vultr/auditrecords.go @@ -17,7 +17,7 @@ func AuditRecords(records []*models.RecordConfig) []error { // Needs investigation. Could be a dnscontrol issue or // the provider doesn't support double quotes. - a.Add("TXT", rejectif.TxtHasMultipleSegments) + a.Add("TXT", rejectif.TxtLongerThan255) a.Add("CAA", rejectif.CaaTargetContainsWhitespace) // Last verified 2023-01-19