| 1 | package dnsrec |
| 2 | |
| 3 | import "testing" |
| 4 | |
| 5 | // Route53 stores a TXT value as a quoted character-string. SPF and DMARC |
| 6 | // values contain spaces and semicolons, so an unquoted value is either |
| 7 | // rejected or silently stored as something no resolver will match — which |
| 8 | // looks like "DNS published, verification still pending" forever. |
| 9 | func TestTXTValuesAreQuoted(t *testing.T) { |
| 10 | got := quoteTXT(`v=DMARC1; p=none; adkim=s; aspf=s`) |
| 11 | want := `"v=DMARC1; p=none; adkim=s; aspf=s"` |
| 12 | if got != want { |
| 13 | t.Fatalf("quoteTXT = %s, want %s", got, want) |
| 14 | } |
| 15 | } |
| 16 | |
| 17 | // A TXT value with an embedded quote must be escaped, not truncated. |
| 18 | func TestTXTQuotingEscapes(t *testing.T) { |
| 19 | if got := quoteTXT(`a"b`); got != `"a\"b"` { |
| 20 | t.Fatalf("quoteTXT = %s, want %s", got, `"a\"b"`) |
| 21 | } |
| 22 | } |
| 23 | |
| 24 | // A CNAME or MX value is NOT quoted — quoting one produces a record Route53 |
| 25 | // accepts and no resolver can follow. |
| 26 | func TestNonTXTValuesAreNotQuoted(t *testing.T) { |
| 27 | for _, typ := range []string{TypeCNAME, TypeMX} { |
| 28 | if got := renderValue(typ, "x.dkim.amazonses.com"); got != "x.dkim.amazonses.com" { |
| 29 | t.Fatalf("renderValue(%s) = %q, want unquoted", typ, got) |
| 30 | } |
| 31 | } |
| 32 | if got := renderValue(TypeTXT, "hello"); got != `"hello"` { |
| 33 | t.Fatalf("renderValue(TXT) = %q, want quoted", got) |
| 34 | } |
| 35 | } |
| 36 | |