lego/acme/dns_challenge_test.go

322 lines
6.5 KiB
Go
Raw Normal View History

package acme
import (
"bufio"
2016-01-27 01:01:58 +00:00
"crypto/rand"
"crypto/rsa"
"net/http"
"net/http/httptest"
"os"
"sort"
"testing"
"time"
2018-09-15 17:16:35 +00:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDNSValidServerResponse(t *testing.T) {
PreCheckDNS = func(fqdn, value string) (bool, error) {
return true, nil
}
2018-09-15 17:16:35 +00:00
privKey, err := rsa.GenerateKey(rand.Reader, 512)
require.NoError(t, err)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Replay-Nonce", "12345")
_, err = w.Write([]byte("{\"type\":\"dns01\",\"status\":\"valid\",\"uri\":\"http://some.url\",\"token\":\"http8\"}"))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}))
go func() {
time.Sleep(time.Second * 2)
f := bufio.NewWriter(os.Stdout)
defer f.Flush()
_, _ = f.WriteString("\n")
}()
2018-09-15 17:16:35 +00:00
manualProvider, err := NewDNSProviderManual()
require.NoError(t, err)
clientChallenge := challenge{Type: "dns01", Status: "pending", URL: ts.URL, Token: "http8"}
solver := &dnsChallenge{
jws: &jws{privKey: privKey, getNonceURL: ts.URL},
validate: validate,
provider: manualProvider,
}
2018-09-15 17:16:35 +00:00
err = solver.Solve(clientChallenge, "example.com")
require.NoError(t, err)
}
func TestPreCheckDNS(t *testing.T) {
ok, err := PreCheckDNS("acme-staging.api.letsencrypt.org", "fe01=")
if err != nil || !ok {
2018-09-15 17:16:35 +00:00
t.Errorf("PreCheckDNS failed for acme-staging.api.letsencrypt.org")
}
}
func TestLookupNameserversOK(t *testing.T) {
2018-09-15 17:16:35 +00:00
testCases := []struct {
fqdn string
nss []string
}{
{
fqdn: "books.google.com.ng.",
nss: []string{"ns1.google.com.", "ns2.google.com.", "ns3.google.com.", "ns4.google.com."},
},
{
fqdn: "www.google.com.",
nss: []string{"ns1.google.com.", "ns2.google.com.", "ns3.google.com.", "ns4.google.com."},
},
{
fqdn: "physics.georgetown.edu.",
nss: []string{"ns1.georgetown.edu.", "ns2.georgetown.edu.", "ns3.georgetown.edu."},
},
}
2018-09-15 17:16:35 +00:00
for _, test := range testCases {
test := test
t.Run(test.fqdn, func(t *testing.T) {
t.Parallel()
2018-09-15 17:16:35 +00:00
nss, err := lookupNameservers(test.fqdn)
require.NoError(t, err)
sort.Strings(nss)
sort.Strings(test.nss)
assert.EqualValues(t, test.nss, nss)
})
}
}
func TestLookupNameserversErr(t *testing.T) {
2018-09-15 17:16:35 +00:00
testCases := []struct {
desc string
fqdn string
error string
}{
{
desc: "invalid tld",
fqdn: "_null.n0n0.",
error: "could not determine the zone",
},
}
2018-09-15 17:16:35 +00:00
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
_, err := lookupNameservers(test.fqdn)
require.Error(t, err)
assert.Contains(t, err.Error(), test.error)
})
}
}
func TestFindZoneByFqdn(t *testing.T) {
2018-09-15 17:16:35 +00:00
testCases := []struct {
desc string
fqdn string
zone string
}{
{
desc: "domain is a CNAME",
fqdn: "mail.google.com.",
zone: "google.com.",
},
{
desc: "domain is a non-existent subdomain",
fqdn: "foo.google.com.",
zone: "google.com.",
},
{
desc: "domain is a eTLD",
fqdn: "example.com.ac.",
zone: "ac.",
},
{
desc: "domain is a cross-zone CNAME",
fqdn: "cross-zone-example.assets.sh.",
zone: "assets.sh.",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
zone, err := FindZoneByFqdn(test.fqdn, RecursiveNameservers)
require.NoError(t, err)
assert.Equal(t, test.zone, zone)
})
}
}
func TestCheckAuthoritativeNss(t *testing.T) {
2018-09-15 17:16:35 +00:00
testCases := []struct {
desc string
fqdn, value string
ns []string
expected bool
}{
{
desc: "TXT RR w/ expected value",
fqdn: "8.8.8.8.asn.routeviews.org.",
value: "151698.8.8.024",
ns: []string{"asnums.routeviews.org."},
expected: true,
},
{
desc: "No TXT RR",
fqdn: "ns1.google.com.",
ns: []string{"ns2.google.com."},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
ok, _ := checkAuthoritativeNss(test.fqdn, test.value, test.ns)
assert.Equal(t, test.expected, ok, test.fqdn)
})
}
}
func TestCheckAuthoritativeNssErr(t *testing.T) {
2018-09-15 17:16:35 +00:00
testCases := []struct {
desc string
fqdn, value string
ns []string
error string
}{
{
desc: "TXT RR /w unexpected value",
fqdn: "8.8.8.8.asn.routeviews.org.",
value: "fe01=",
ns: []string{"asnums.routeviews.org."},
error: "did not return the expected TXT record",
},
{
desc: "No TXT RR",
fqdn: "ns1.google.com.",
value: "fe01=",
ns: []string{"ns2.google.com."},
error: "did not return the expected TXT record",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
_, err := checkAuthoritativeNss(test.fqdn, test.value, test.ns)
require.Error(t, err)
assert.Contains(t, err.Error(), test.error)
})
}
}
func TestResolveConfServers(t *testing.T) {
2018-09-15 17:16:35 +00:00
var testCases = []struct {
fixture string
expected []string
defaults []string
}{
{
fixture: "testdata/resolv.conf.1",
defaults: []string{"127.0.0.1:53"},
expected: []string{"10.200.3.249:53", "10.200.3.250:5353", "[2001:4860:4860::8844]:53", "[10.0.0.1]:5353"},
},
{
fixture: "testdata/resolv.conf.nonexistant",
defaults: []string{"127.0.0.1:53"},
expected: []string{"127.0.0.1:53"},
},
}
for _, test := range testCases {
t.Run(test.fixture, func(t *testing.T) {
result := getNameservers(test.fixture, test.defaults)
sort.Strings(result)
sort.Strings(test.expected)
assert.Equal(t, test.expected, result)
})
}
}
func TestToFqdn(t *testing.T) {
testCases := []struct {
desc string
domain string
expected string
}{
{
desc: "simple",
domain: "foo.bar.com",
expected: "foo.bar.com.",
},
{
desc: "already FQDN",
domain: "foo.bar.com.",
expected: "foo.bar.com.",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
fqdn := ToFqdn(test.domain)
assert.Equal(t, test.expected, fqdn)
})
}
}
func TestUnFqdn(t *testing.T) {
testCases := []struct {
desc string
fqdn string
expected string
}{
{
desc: "simple",
fqdn: "foo.bar.com.",
expected: "foo.bar.com",
},
{
desc: "already domain",
fqdn: "foo.bar.com",
expected: "foo.bar.com",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
domain := UnFqdn(test.fqdn)
assert.Equal(t, test.expected, domain)
})
}
}