Report DNS errors properly.
Previously we would return a detailed errorString, which ProblemDetailsFromDNSError would turn into a generic, uninformative "Server failure at resolver". Now we return a new internal dnsError type, which ProblemDetailsFromDNSError can turn into a more informative message to be shown to the user.
This commit is contained in:
parent
2b15b6cc33
commit
df4ba7aaa8
38
bdns/dns.go
38
bdns/dns.go
|
|
@ -201,24 +201,24 @@ func (dnsResolver *DNSResolverImpl) exchangeOne(hostname string, qtype uint16, m
|
||||||
// the provided hostname.
|
// the provided hostname.
|
||||||
func (dnsResolver *DNSResolverImpl) LookupTXT(hostname string) ([]string, error) {
|
func (dnsResolver *DNSResolverImpl) LookupTXT(hostname string) ([]string, error) {
|
||||||
var txt []string
|
var txt []string
|
||||||
r, err := dnsResolver.exchangeOne(hostname, dns.TypeTXT, dnsResolver.txtStats)
|
dnsType := dns.TypeTXT
|
||||||
|
r, err := dnsResolver.exchangeOne(hostname, dnsType, dnsResolver.txtStats)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, &dnsError{dnsType, hostname, err, -1}
|
||||||
}
|
}
|
||||||
if r.Rcode != dns.RcodeSuccess {
|
if r.Rcode != dns.RcodeSuccess {
|
||||||
err = fmt.Errorf("DNS failure: %d-%s for TXT query", r.Rcode, dns.RcodeToString[r.Rcode])
|
return nil, &dnsError{dnsType, hostname, nil, r.Rcode}
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, answer := range r.Answer {
|
for _, answer := range r.Answer {
|
||||||
if answer.Header().Rrtype == dns.TypeTXT {
|
if answer.Header().Rrtype == dnsType {
|
||||||
if txtRec, ok := answer.(*dns.TXT); ok {
|
if txtRec, ok := answer.(*dns.TXT); ok {
|
||||||
txt = append(txt, strings.Join(txtRec.Txt, ""))
|
txt = append(txt, strings.Join(txtRec.Txt, ""))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return txt, err
|
return txt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func isPrivateV4(ip net.IP) bool {
|
func isPrivateV4(ip net.IP) bool {
|
||||||
|
|
@ -235,18 +235,17 @@ func isPrivateV4(ip net.IP) bool {
|
||||||
// aliases and return relevant A records.
|
// aliases and return relevant A records.
|
||||||
func (dnsResolver *DNSResolverImpl) LookupHost(hostname string) ([]net.IP, error) {
|
func (dnsResolver *DNSResolverImpl) LookupHost(hostname string) ([]net.IP, error) {
|
||||||
var addrs []net.IP
|
var addrs []net.IP
|
||||||
|
dnsType := dns.TypeA
|
||||||
r, err := dnsResolver.exchangeOne(hostname, dns.TypeA, dnsResolver.aStats)
|
r, err := dnsResolver.exchangeOne(hostname, dnsType, dnsResolver.aStats)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return addrs, err
|
return addrs, &dnsError{dnsType, hostname, err, -1}
|
||||||
}
|
}
|
||||||
if r.Rcode != dns.RcodeSuccess {
|
if r.Rcode != dns.RcodeSuccess {
|
||||||
err = fmt.Errorf("DNS failure: %d-%s for A query", r.Rcode, dns.RcodeToString[r.Rcode])
|
return nil, &dnsError{dnsType, hostname, nil, r.Rcode}
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, answer := range r.Answer {
|
for _, answer := range r.Answer {
|
||||||
if answer.Header().Rrtype == dns.TypeA {
|
if answer.Header().Rrtype == dnsType {
|
||||||
if a, ok := answer.(*dns.A); ok && a.A.To4() != nil && (!isPrivateV4(a.A) || dnsResolver.allowRestrictedAddresses) {
|
if a, ok := answer.(*dns.A); ok && a.A.To4() != nil && (!isPrivateV4(a.A) || dnsResolver.allowRestrictedAddresses) {
|
||||||
addrs = append(addrs, a.A)
|
addrs = append(addrs, a.A)
|
||||||
}
|
}
|
||||||
|
|
@ -260,9 +259,10 @@ func (dnsResolver *DNSResolverImpl) LookupHost(hostname string) ([]net.IP, error
|
||||||
// the provided hostname. If the response code from the resolver is
|
// the provided hostname. If the response code from the resolver is
|
||||||
// SERVFAIL an empty slice of CAA records is returned.
|
// SERVFAIL an empty slice of CAA records is returned.
|
||||||
func (dnsResolver *DNSResolverImpl) LookupCAA(hostname string) ([]*dns.CAA, error) {
|
func (dnsResolver *DNSResolverImpl) LookupCAA(hostname string) ([]*dns.CAA, error) {
|
||||||
r, err := dnsResolver.exchangeOne(hostname, dns.TypeCAA, dnsResolver.caaStats)
|
dnsType := dns.TypeCAA
|
||||||
|
r, err := dnsResolver.exchangeOne(hostname, dnsType, dnsResolver.caaStats)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, &dnsError{dnsType, hostname, err, -1}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On resolver validation failure, or other server failures, return empty an
|
// On resolver validation failure, or other server failures, return empty an
|
||||||
|
|
@ -273,7 +273,7 @@ func (dnsResolver *DNSResolverImpl) LookupCAA(hostname string) ([]*dns.CAA, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, answer := range r.Answer {
|
for _, answer := range r.Answer {
|
||||||
if answer.Header().Rrtype == dns.TypeCAA {
|
if answer.Header().Rrtype == dnsType {
|
||||||
if caaR, ok := answer.(*dns.CAA); ok {
|
if caaR, ok := answer.(*dns.CAA); ok {
|
||||||
CAAs = append(CAAs, caaR)
|
CAAs = append(CAAs, caaR)
|
||||||
}
|
}
|
||||||
|
|
@ -285,13 +285,13 @@ func (dnsResolver *DNSResolverImpl) LookupCAA(hostname string) ([]*dns.CAA, erro
|
||||||
// LookupMX sends a DNS query to find a MX record associated hostname and returns the
|
// LookupMX sends a DNS query to find a MX record associated hostname and returns the
|
||||||
// record target.
|
// record target.
|
||||||
func (dnsResolver *DNSResolverImpl) LookupMX(hostname string) ([]string, error) {
|
func (dnsResolver *DNSResolverImpl) LookupMX(hostname string) ([]string, error) {
|
||||||
r, err := dnsResolver.exchangeOne(hostname, dns.TypeMX, dnsResolver.mxStats)
|
dnsType := dns.TypeMX
|
||||||
|
r, err := dnsResolver.exchangeOne(hostname, dnsType, dnsResolver.mxStats)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, &dnsError{dnsType, hostname, err, -1}
|
||||||
}
|
}
|
||||||
if r.Rcode != dns.RcodeSuccess {
|
if r.Rcode != dns.RcodeSuccess {
|
||||||
err = fmt.Errorf("DNS failure: %d-%s for MX query", r.Rcode, dns.RcodeToString[r.Rcode])
|
return nil, &dnsError{dnsType, hostname, nil, r.Rcode}
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var results []string
|
var results []string
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,9 @@ func mockDNSQuery(w dns.ResponseWriter, r *dns.Msg) {
|
||||||
record.A = net.ParseIP("127.0.0.1")
|
record.A = net.ParseIP("127.0.0.1")
|
||||||
appendAnswer(record)
|
appendAnswer(record)
|
||||||
}
|
}
|
||||||
|
if q.Name == "nxdomain.letsencrypt.org." {
|
||||||
|
m.SetRcode(r, dns.RcodeNameError)
|
||||||
|
}
|
||||||
case dns.TypeCNAME:
|
case dns.TypeCNAME:
|
||||||
if q.Name == "cname.letsencrypt.org." {
|
if q.Name == "cname.letsencrypt.org." {
|
||||||
record := new(dns.CNAME)
|
record := new(dns.CNAME)
|
||||||
|
|
@ -105,6 +108,9 @@ func mockDNSQuery(w dns.ResponseWriter, r *dns.Msg) {
|
||||||
record.Txt = []string{"a", "b", "c"}
|
record.Txt = []string{"a", "b", "c"}
|
||||||
appendAnswer(record)
|
appendAnswer(record)
|
||||||
}
|
}
|
||||||
|
if q.Name == "nxdomain.letsencrypt.org." {
|
||||||
|
m.SetRcode(r, dns.RcodeNameError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,6 +254,23 @@ func TestDNSLookupHost(t *testing.T) {
|
||||||
test.Assert(t, len(ip) == 0, "Should not have IPs")
|
test.Assert(t, len(ip) == 0, "Should not have IPs")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDNSNXDOMAIN(t *testing.T) {
|
||||||
|
obj := NewTestDNSResolverImpl(time.Second*10, []string{dnsLoopbackAddr}, testStats)
|
||||||
|
|
||||||
|
hostname := "nxdomain.letsencrypt.org"
|
||||||
|
_, err := obj.LookupHost(hostname)
|
||||||
|
expected := dnsError{dns.TypeA, hostname, nil, dns.RcodeNameError}
|
||||||
|
if err, ok := err.(*dnsError); !ok || *err != expected {
|
||||||
|
t.Errorf("Looking up %s, got %#v, expected %#v", hostname, err, expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = obj.LookupTXT(hostname)
|
||||||
|
expected.recordType = dns.TypeTXT
|
||||||
|
if err, ok := err.(*dnsError); !ok || *err != expected {
|
||||||
|
t.Errorf("Looking up %s, got %#v, expected %#v", hostname, err, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDNSLookupCAA(t *testing.T) {
|
func TestDNSLookupCAA(t *testing.T) {
|
||||||
obj := NewTestDNSResolverImpl(time.Second*10, []string{dnsLoopbackAddr}, testStats)
|
obj := NewTestDNSResolverImpl(time.Second*10, []string{dnsLoopbackAddr}, testStats)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
package bdns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/miekg/dns"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockDNSResolver is a mock
|
||||||
|
type MockDNSResolver struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupTXT is a mock
|
||||||
|
func (mock *MockDNSResolver) LookupTXT(hostname string) ([]string, error) {
|
||||||
|
if hostname == "_acme-challenge.servfail.com" {
|
||||||
|
return nil, fmt.Errorf("SERVFAIL")
|
||||||
|
}
|
||||||
|
if hostname == "_acme-challenge.good-dns01.com" {
|
||||||
|
// base64(sha256("LoqXcYV8q5ONbJQxbmR7SCTNo3tiAXDfowyjxAjEuX0"
|
||||||
|
// + "." + "9jg46WB3rR_AHD-EBXdN7cBkH1WOu0tA3M9fm21mqTI"))
|
||||||
|
// expected token + test account jwk thumbprint
|
||||||
|
return []string{"LPsIwTo7o8BoG0-vjCyGQGBWSVIPxI-i_X336eUOQZo"}, nil
|
||||||
|
}
|
||||||
|
return []string{"hostname"}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockTimeoutError returns a a net.OpError for which Timeout() returns true.
|
||||||
|
func MockTimeoutError() *net.OpError {
|
||||||
|
return &net.OpError{
|
||||||
|
Err: os.NewSyscallError("ugh timeout", timeoutError{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type timeoutError struct{}
|
||||||
|
|
||||||
|
func (t timeoutError) Error() string {
|
||||||
|
return "so sloooow"
|
||||||
|
}
|
||||||
|
func (t timeoutError) Timeout() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupHost is a mock
|
||||||
|
//
|
||||||
|
// Note: see comments on LookupMX regarding email.only
|
||||||
|
//
|
||||||
|
func (mock *MockDNSResolver) LookupHost(hostname string) ([]net.IP, error) {
|
||||||
|
if hostname == "always.invalid" ||
|
||||||
|
hostname == "invalid.invalid" ||
|
||||||
|
hostname == "email.only" {
|
||||||
|
return []net.IP{}, nil
|
||||||
|
}
|
||||||
|
if hostname == "always.timeout" {
|
||||||
|
return []net.IP{}, &dnsError{dns.TypeA, "always.timeout", MockTimeoutError(), -1}
|
||||||
|
}
|
||||||
|
if hostname == "always.error" {
|
||||||
|
return []net.IP{}, &dnsError{dns.TypeA, "always.error", &net.OpError{
|
||||||
|
Err: errors.New("some net error"),
|
||||||
|
}, -1}
|
||||||
|
}
|
||||||
|
ip := net.ParseIP("127.0.0.1")
|
||||||
|
return []net.IP{ip}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupCAA is a mock
|
||||||
|
func (mock *MockDNSResolver) LookupCAA(domain string) ([]*dns.CAA, error) {
|
||||||
|
var results []*dns.CAA
|
||||||
|
var record dns.CAA
|
||||||
|
switch strings.TrimRight(domain, ".") {
|
||||||
|
case "caa-timeout.com":
|
||||||
|
return nil, &dnsError{dns.TypeCAA, "always.timeout", MockTimeoutError(), -1}
|
||||||
|
case "reserved.com":
|
||||||
|
record.Tag = "issue"
|
||||||
|
record.Value = "symantec.com"
|
||||||
|
results = append(results, &record)
|
||||||
|
case "critical.com":
|
||||||
|
record.Flag = 1
|
||||||
|
record.Tag = "issue"
|
||||||
|
record.Value = "symantec.com"
|
||||||
|
results = append(results, &record)
|
||||||
|
case "present.com":
|
||||||
|
record.Tag = "issue"
|
||||||
|
record.Value = "letsencrypt.org"
|
||||||
|
results = append(results, &record)
|
||||||
|
case "com":
|
||||||
|
// Nothing should ever call this, since CAA checking should stop when it
|
||||||
|
// reaches a public suffix.
|
||||||
|
fallthrough
|
||||||
|
case "servfail.com":
|
||||||
|
return results, fmt.Errorf("SERVFAIL")
|
||||||
|
}
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LookupMX is a mock
|
||||||
|
//
|
||||||
|
// Note: the email.only domain must have an MX but no A or AAAA
|
||||||
|
// records. The mock LookupHost returns an address of 127.0.0.1 for
|
||||||
|
// all domains except for special cases, so MX-only domains must be
|
||||||
|
// handled in both LookupHost and LookupMX.
|
||||||
|
//
|
||||||
|
func (mock *MockDNSResolver) LookupMX(domain string) ([]string, error) {
|
||||||
|
switch strings.TrimRight(domain, ".") {
|
||||||
|
case "letsencrypt.org":
|
||||||
|
fallthrough
|
||||||
|
case "email.only":
|
||||||
|
fallthrough
|
||||||
|
case "email.com":
|
||||||
|
return []string{"mail.email.com"}, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
@ -9,30 +9,55 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/miekg/dns"
|
||||||
"github.com/letsencrypt/boulder/probs"
|
"github.com/letsencrypt/boulder/probs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const detailDNSTimeout = "DNS query timed out"
|
type dnsError struct {
|
||||||
const detailDNSNetFailure = "DNS networking error"
|
recordType uint16
|
||||||
const detailServerFailure = "Server failure at resolver"
|
hostname string
|
||||||
|
// Exactly one of rCode or underlying should be set.
|
||||||
|
underlying error
|
||||||
|
rCode int
|
||||||
|
}
|
||||||
|
|
||||||
// ProblemDetailsFromDNSError checks the error returned from Lookup... methods
|
func (d dnsError) Error() string {
|
||||||
// and tests if the error was an underlying net.OpError or an error caused by
|
var detail string
|
||||||
// resolver returning SERVFAIL or other invalid Rcodes and returns the relevant
|
if d.underlying != nil {
|
||||||
// core.ProblemDetails. The detail string will contain a mention of the DNS
|
if netErr, ok := d.underlying.(*net.OpError); ok {
|
||||||
// record type and domain given.
|
|
||||||
func ProblemDetailsFromDNSError(recordType, domain string, err error) *probs.ProblemDetails {
|
|
||||||
detail := detailServerFailure
|
|
||||||
if netErr, ok := err.(*net.OpError); ok {
|
|
||||||
if netErr.Timeout() {
|
if netErr.Timeout() {
|
||||||
detail = detailDNSTimeout
|
detail = detailDNSTimeout
|
||||||
} else {
|
} else {
|
||||||
detail = detailDNSNetFailure
|
detail = detailDNSNetFailure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
detail = fmt.Sprintf("%s during %s-record lookup of %s", detail, recordType, domain)
|
} else if d.rCode != dns.RcodeSuccess {
|
||||||
|
detail = dns.RcodeToString[d.rCode]
|
||||||
|
} else {
|
||||||
|
detail = detailServerFailure
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("DNS problem: %s looking up %s for %s", detail,
|
||||||
|
dns.TypeToString[d.recordType], d.hostname)
|
||||||
|
}
|
||||||
|
|
||||||
|
const detailDNSTimeout = "query timed out"
|
||||||
|
const detailDNSNetFailure = "networking error"
|
||||||
|
const detailServerFailure = "server failure at resolver"
|
||||||
|
|
||||||
|
// ProblemDetailsFromDNSError checks the error returned from Lookup... methods
|
||||||
|
// and tests if the error was an underlying net.OpError or an error caused by
|
||||||
|
// resolver returning SERVFAIL or other invalid Rcodes and returns the relevant
|
||||||
|
// core.ProblemDetails. The detail string will contain a mention of the DNS
|
||||||
|
// record type and domain given.
|
||||||
|
func ProblemDetailsFromDNSError(err error) *probs.ProblemDetails {
|
||||||
|
if dnsErr, ok := err.(*dnsError); ok {
|
||||||
return &probs.ProblemDetails{
|
return &probs.ProblemDetails{
|
||||||
Type: probs.ConnectionProblem,
|
Type: probs.ConnectionProblem,
|
||||||
Detail: detail,
|
Detail: dnsErr.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &probs.ProblemDetails{
|
||||||
|
Type: probs.ConnectionProblem,
|
||||||
|
Detail: detailServerFailure,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/letsencrypt/boulder/mocks"
|
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/miekg/dns"
|
||||||
|
|
||||||
"github.com/letsencrypt/boulder/probs"
|
"github.com/letsencrypt/boulder/probs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -20,23 +21,25 @@ func TestProblemDetailsFromDNSError(t *testing.T) {
|
||||||
expected string
|
expected string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
mocks.TimeoutError(),
|
&dnsError{dns.TypeA, "hostname", MockTimeoutError(), -1},
|
||||||
detailDNSTimeout,
|
"DNS problem: query timed out looking up A for hostname",
|
||||||
}, {
|
}, {
|
||||||
errors.New("other failure"),
|
errors.New("other failure"),
|
||||||
detailServerFailure,
|
detailServerFailure,
|
||||||
}, {
|
}, {
|
||||||
&net.OpError{Err: errors.New("some net error")},
|
&dnsError{dns.TypeMX, "hostname", &net.OpError{Err: errors.New("some net error")}, -1},
|
||||||
detailDNSNetFailure,
|
"DNS problem: networking error looking up MX for hostname",
|
||||||
|
}, {
|
||||||
|
&dnsError{dns.TypeTXT, "hostname", nil, dns.RcodeNameError},
|
||||||
|
"DNS problem: NXDOMAIN looking up TXT for hostname",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
err := ProblemDetailsFromDNSError("TXT", "example.com", tc.err)
|
err := ProblemDetailsFromDNSError(tc.err)
|
||||||
if err.Type != probs.ConnectionProblem {
|
if err.Type != probs.ConnectionProblem {
|
||||||
t.Errorf("ProblemDetailsFromDNSError(%q).Type = %q, expected %q", tc.err, err.Type, probs.ConnectionProblem)
|
t.Errorf("ProblemDetailsFromDNSError(%q).Type = %q, expected %q", tc.err, err.Type, probs.ConnectionProblem)
|
||||||
}
|
}
|
||||||
exp := tc.expected + " during TXT-record lookup of example.com"
|
if err.Detail != tc.expected {
|
||||||
if err.Detail != exp {
|
|
||||||
t.Errorf("ProblemDetailsFromDNSError(%q).Detail = %q, expected %q", tc.err, err.Detail, tc.expected)
|
t.Errorf("ProblemDetailsFromDNSError(%q).Detail = %q, expected %q", tc.err, err.Detail, tc.expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
108
mocks/mocks.go
108
mocks/mocks.go
|
|
@ -12,8 +12,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
|
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cactus/go-statsd-client/statsd"
|
||||||
|
|
@ -23,116 +21,10 @@ import (
|
||||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer"
|
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer"
|
||||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/jmhodges/clock"
|
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/jmhodges/clock"
|
||||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/letsencrypt/go-jose"
|
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/letsencrypt/go-jose"
|
||||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/miekg/dns"
|
|
||||||
|
|
||||||
"github.com/letsencrypt/boulder/core"
|
"github.com/letsencrypt/boulder/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DNSResolver is a mock
|
|
||||||
type DNSResolver struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// LookupTXT is a mock
|
|
||||||
func (mock *DNSResolver) LookupTXT(hostname string) ([]string, error) {
|
|
||||||
if hostname == "_acme-challenge.servfail.com" {
|
|
||||||
return nil, fmt.Errorf("SERVFAIL")
|
|
||||||
}
|
|
||||||
if hostname == "_acme-challenge.good-dns01.com" {
|
|
||||||
// base64(sha256("LoqXcYV8q5ONbJQxbmR7SCTNo3tiAXDfowyjxAjEuX0"
|
|
||||||
// + "." + "9jg46WB3rR_AHD-EBXdN7cBkH1WOu0tA3M9fm21mqTI"))
|
|
||||||
// expected token + test account jwk thumbprint
|
|
||||||
return []string{"LPsIwTo7o8BoG0-vjCyGQGBWSVIPxI-i_X336eUOQZo"}, nil
|
|
||||||
}
|
|
||||||
return []string{"hostname"}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeoutError returns a a net.OpError for which Timeout() returns true.
|
|
||||||
func TimeoutError() *net.OpError {
|
|
||||||
return &net.OpError{
|
|
||||||
Err: os.NewSyscallError("ugh timeout", timeoutError{}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type timeoutError struct{}
|
|
||||||
|
|
||||||
func (t timeoutError) Error() string {
|
|
||||||
return "so sloooow"
|
|
||||||
}
|
|
||||||
func (t timeoutError) Timeout() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// LookupHost is a mock
|
|
||||||
//
|
|
||||||
// Note: see comments on LookupMX regarding email.only
|
|
||||||
//
|
|
||||||
func (mock *DNSResolver) LookupHost(hostname string) ([]net.IP, error) {
|
|
||||||
if hostname == "always.invalid" ||
|
|
||||||
hostname == "invalid.invalid" ||
|
|
||||||
hostname == "email.only" {
|
|
||||||
return []net.IP{}, nil
|
|
||||||
}
|
|
||||||
if hostname == "always.timeout" {
|
|
||||||
return []net.IP{}, TimeoutError()
|
|
||||||
}
|
|
||||||
if hostname == "always.error" {
|
|
||||||
return []net.IP{}, &net.OpError{
|
|
||||||
Err: errors.New("some net error"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ip := net.ParseIP("127.0.0.1")
|
|
||||||
return []net.IP{ip}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LookupCAA is a mock
|
|
||||||
func (mock *DNSResolver) LookupCAA(domain string) ([]*dns.CAA, error) {
|
|
||||||
var results []*dns.CAA
|
|
||||||
var record dns.CAA
|
|
||||||
switch strings.TrimRight(domain, ".") {
|
|
||||||
case "caa-timeout.com":
|
|
||||||
return nil, TimeoutError()
|
|
||||||
case "reserved.com":
|
|
||||||
record.Tag = "issue"
|
|
||||||
record.Value = "symantec.com"
|
|
||||||
results = append(results, &record)
|
|
||||||
case "critical.com":
|
|
||||||
record.Flag = 1
|
|
||||||
record.Tag = "issue"
|
|
||||||
record.Value = "symantec.com"
|
|
||||||
results = append(results, &record)
|
|
||||||
case "present.com":
|
|
||||||
record.Tag = "issue"
|
|
||||||
record.Value = "letsencrypt.org"
|
|
||||||
results = append(results, &record)
|
|
||||||
case "com":
|
|
||||||
// Nothing should ever call this, since CAA checking should stop when it
|
|
||||||
// reaches a public suffix.
|
|
||||||
fallthrough
|
|
||||||
case "servfail.com":
|
|
||||||
return results, fmt.Errorf("SERVFAIL")
|
|
||||||
}
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LookupMX is a mock
|
|
||||||
//
|
|
||||||
// Note: the email.only domain must have an MX but no A or AAAA
|
|
||||||
// records. The mock LookupHost returns an address of 127.0.0.1 for
|
|
||||||
// all domains except for special cases, so MX-only domains must be
|
|
||||||
// handled in both LookupHost and LookupMX.
|
|
||||||
//
|
|
||||||
func (mock *DNSResolver) LookupMX(domain string) ([]string, error) {
|
|
||||||
switch strings.TrimRight(domain, ".") {
|
|
||||||
case "letsencrypt.org":
|
|
||||||
fallthrough
|
|
||||||
case "email.only":
|
|
||||||
fallthrough
|
|
||||||
case "email.com":
|
|
||||||
return []string{"mail.email.com"}, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StorageAuthority is a mock
|
// StorageAuthority is a mock
|
||||||
type StorageAuthority struct {
|
type StorageAuthority struct {
|
||||||
clk clock.Clock
|
clk clock.Clock
|
||||||
|
|
|
||||||
|
|
@ -97,10 +97,8 @@ func validateEmail(address string, resolver bdns.DNSResolver) (prob *probs.Probl
|
||||||
var resultMX []string
|
var resultMX []string
|
||||||
var resultA []net.IP
|
var resultA []net.IP
|
||||||
resultMX, err = resolver.LookupMX(domain)
|
resultMX, err = resolver.LookupMX(domain)
|
||||||
recQ := "MX"
|
|
||||||
if err == nil && len(resultMX) == 0 {
|
if err == nil && len(resultMX) == 0 {
|
||||||
resultA, err = resolver.LookupHost(domain)
|
resultA, err = resolver.LookupHost(domain)
|
||||||
recQ = "A"
|
|
||||||
if err == nil && len(resultA) == 0 {
|
if err == nil && len(resultA) == 0 {
|
||||||
return &probs.ProblemDetails{
|
return &probs.ProblemDetails{
|
||||||
Type: probs.InvalidEmailProblem,
|
Type: probs.InvalidEmailProblem,
|
||||||
|
|
@ -109,7 +107,7 @@ func validateEmail(address string, resolver bdns.DNSResolver) (prob *probs.Probl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
prob := bdns.ProblemDetailsFromDNSError(recQ, domain, err)
|
prob := bdns.ProblemDetailsFromDNSError(err)
|
||||||
prob.Type = probs.InvalidEmailProblem
|
prob.Type = probs.InvalidEmailProblem
|
||||||
return prob
|
return prob
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import (
|
||||||
cfsslConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config"
|
cfsslConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config"
|
||||||
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/jmhodges/clock"
|
"github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/jmhodges/clock"
|
||||||
jose "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/letsencrypt/go-jose"
|
jose "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/letsencrypt/go-jose"
|
||||||
|
"github.com/letsencrypt/boulder/bdns"
|
||||||
"github.com/letsencrypt/boulder/ca"
|
"github.com/letsencrypt/boulder/ca"
|
||||||
"github.com/letsencrypt/boulder/cmd"
|
"github.com/letsencrypt/boulder/cmd"
|
||||||
"github.com/letsencrypt/boulder/core"
|
"github.com/letsencrypt/boulder/core"
|
||||||
|
|
@ -246,7 +247,7 @@ func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAut
|
||||||
ra.VA = va
|
ra.VA = va
|
||||||
ra.CA = ca
|
ra.CA = ca
|
||||||
ra.PA = pa
|
ra.PA = pa
|
||||||
ra.DNSResolver = &mocks.DNSResolver{}
|
ra.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
|
|
||||||
AuthzInitial.RegistrationID = Registration.ID
|
AuthzInitial.RegistrationID = Registration.ID
|
||||||
|
|
||||||
|
|
@ -317,15 +318,15 @@ func TestValidateEmail(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{"an email`", unparseableEmailDetail},
|
{"an email`", unparseableEmailDetail},
|
||||||
{"a@always.invalid", emptyDNSResponseDetail},
|
{"a@always.invalid", emptyDNSResponseDetail},
|
||||||
{"a@always.timeout", "DNS query timed out during A-record lookup of always.timeout"},
|
{"a@always.timeout", "DNS problem: query timed out looking up A for always.timeout"},
|
||||||
{"a@always.error", "DNS networking error during A-record lookup of always.error"},
|
{"a@always.error", "DNS problem: networking error looking up A for always.error"},
|
||||||
}
|
}
|
||||||
testSuccesses := []string{
|
testSuccesses := []string{
|
||||||
"a@email.com",
|
"a@email.com",
|
||||||
"b@email.only",
|
"b@email.only",
|
||||||
}
|
}
|
||||||
for _, tc := range testFailures {
|
for _, tc := range testFailures {
|
||||||
problem := validateEmail(tc.input, &mocks.DNSResolver{})
|
problem := validateEmail(tc.input, &bdns.MockDNSResolver{})
|
||||||
if problem.Type != probs.InvalidEmailProblem {
|
if problem.Type != probs.InvalidEmailProblem {
|
||||||
t.Errorf("validateEmail(%q): got problem type %#v, expected %#v", tc.input, problem.Type, probs.InvalidEmailProblem)
|
t.Errorf("validateEmail(%q): got problem type %#v, expected %#v", tc.input, problem.Type, probs.InvalidEmailProblem)
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +337,7 @@ func TestValidateEmail(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, addr := range testSuccesses {
|
for _, addr := range testSuccesses {
|
||||||
if prob := validateEmail(addr, &mocks.DNSResolver{}); prob != nil {
|
if prob := validateEmail(addr, &bdns.MockDNSResolver{}); prob != nil {
|
||||||
t.Errorf("validateEmail(%q): expected success, but it failed: %s",
|
t.Errorf("validateEmail(%q): expected success, but it failed: %s",
|
||||||
addr, prob)
|
addr, prob)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ func (va ValidationAuthorityImpl) getAddr(hostname string) (net.IP, []net.IP, *p
|
||||||
addrs, err := va.DNSResolver.LookupHost(hostname)
|
addrs, err := va.DNSResolver.LookupHost(hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
va.log.Debug(fmt.Sprintf("%s DNS failure: %s", hostname, err))
|
va.log.Debug(fmt.Sprintf("%s DNS failure: %s", hostname, err))
|
||||||
problem := bdns.ProblemDetailsFromDNSError("A", hostname, err)
|
problem := bdns.ProblemDetailsFromDNSError(err)
|
||||||
return net.IP{}, nil, problem
|
return net.IP{}, nil, problem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -435,7 +435,7 @@ func (va *ValidationAuthorityImpl) validateDNS01(identifier core.AcmeIdentifier,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
va.log.Debug(fmt.Sprintf("%s [%s] DNS failure: %s", challenge.Type, identifier, err))
|
va.log.Debug(fmt.Sprintf("%s [%s] DNS failure: %s", challenge.Type, identifier, err))
|
||||||
|
|
||||||
return nil, bdns.ProblemDetailsFromDNSError("TXT", challengeSubdomain, err)
|
return nil, bdns.ProblemDetailsFromDNSError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, element := range txts {
|
for _, element := range txts {
|
||||||
|
|
@ -456,7 +456,7 @@ func (va *ValidationAuthorityImpl) checkCAA(identifier core.AcmeIdentifier, regI
|
||||||
present, valid, err := va.CheckCAARecords(identifier)
|
present, valid, err := va.CheckCAARecords(identifier)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
va.log.Warning(fmt.Sprintf("Problem checking CAA: %s", err))
|
va.log.Warning(fmt.Sprintf("Problem checking CAA: %s", err))
|
||||||
return bdns.ProblemDetailsFromDNSError("CAA", identifier.Value, err)
|
return bdns.ProblemDetailsFromDNSError(err)
|
||||||
}
|
}
|
||||||
// AUDIT[ Certificate Requests ] 11917fa4-10ef-4e0d-9105-bacbe7836a3c
|
// AUDIT[ Certificate Requests ] 11917fa4-10ef-4e0d-9105-bacbe7836a3c
|
||||||
va.log.Audit(fmt.Sprintf("Checked CAA records for %s, registration ID %d [Present: %t, Valid for issuance: %t]", identifier.Value, regID, present, valid))
|
va.log.Audit(fmt.Sprintf("Checked CAA records for %s, registration ID %d [Present: %t, Valid for issuance: %t]", identifier.Value, regID, present, valid))
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,7 @@ func TestHTTP(t *testing.T) {
|
||||||
}
|
}
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: badPort}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: badPort}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
|
|
||||||
_, prob := va.validateHTTP01(ident, chall)
|
_, prob := va.validateHTTP01(ident, chall)
|
||||||
if prob == nil {
|
if prob == nil {
|
||||||
|
|
@ -230,7 +230,7 @@ func TestHTTP(t *testing.T) {
|
||||||
test.AssertEquals(t, prob.Type, probs.ConnectionProblem)
|
test.AssertEquals(t, prob.Type, probs.ConnectionProblem)
|
||||||
|
|
||||||
va = NewValidationAuthorityImpl(&PortConfig{HTTPPort: goodPort}, nil, stats, clock.Default())
|
va = NewValidationAuthorityImpl(&PortConfig{HTTPPort: goodPort}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
|
|
||||||
log.Clear()
|
log.Clear()
|
||||||
t.Logf("Trying to validate: %+v\n", chall)
|
t.Logf("Trying to validate: %+v\n", chall)
|
||||||
|
|
@ -314,7 +314,7 @@ func TestHTTPRedirectLookup(t *testing.T) {
|
||||||
test.AssertNotError(t, err, "failed to get test server port")
|
test.AssertNotError(t, err, "failed to get test server port")
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
|
|
||||||
log.Clear()
|
log.Clear()
|
||||||
setChallengeToken(&chall, pathMoved)
|
setChallengeToken(&chall, pathMoved)
|
||||||
|
|
@ -372,7 +372,7 @@ func TestHTTPRedirectLoop(t *testing.T) {
|
||||||
test.AssertNotError(t, err, "failed to get test server port")
|
test.AssertNotError(t, err, "failed to get test server port")
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
|
|
||||||
log.Clear()
|
log.Clear()
|
||||||
_, prob := va.validateHTTP01(ident, chall)
|
_, prob := va.validateHTTP01(ident, chall)
|
||||||
|
|
@ -392,7 +392,7 @@ func TestHTTPRedirectUserAgent(t *testing.T) {
|
||||||
test.AssertNotError(t, err, "failed to get test server port")
|
test.AssertNotError(t, err, "failed to get test server port")
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
va.UserAgent = rejectUserAgent
|
va.UserAgent = rejectUserAgent
|
||||||
|
|
||||||
setChallengeToken(&chall, pathMoved)
|
setChallengeToken(&chall, pathMoved)
|
||||||
|
|
@ -434,7 +434,7 @@ func TestTLSSNI(t *testing.T) {
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, nil, stats, clock.Default())
|
||||||
|
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
|
|
||||||
log.Clear()
|
log.Clear()
|
||||||
_, prob := va.validateTLSSNI01(ident, chall)
|
_, prob := va.validateTLSSNI01(ident, chall)
|
||||||
|
|
@ -506,7 +506,7 @@ func TestTLSError(t *testing.T) {
|
||||||
test.AssertNotError(t, err, "failed to get test server port")
|
test.AssertNotError(t, err, "failed to get test server port")
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
|
|
||||||
_, prob := va.validateTLSSNI01(ident, chall)
|
_, prob := va.validateTLSSNI01(ident, chall)
|
||||||
if prob == nil {
|
if prob == nil {
|
||||||
|
|
@ -525,7 +525,7 @@ func TestValidateHTTP(t *testing.T) {
|
||||||
test.AssertNotError(t, err, "failed to get test server port")
|
test.AssertNotError(t, err, "failed to get test server port")
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{HTTPPort: port}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
@ -582,7 +582,7 @@ func TestValidateTLSSNI01(t *testing.T) {
|
||||||
|
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
@ -600,7 +600,7 @@ func TestValidateTLSSNI01(t *testing.T) {
|
||||||
func TestValidateTLSSNINotSane(t *testing.T) {
|
func TestValidateTLSSNINotSane(t *testing.T) {
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default()) // no calls made
|
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default()) // no calls made
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
@ -622,7 +622,7 @@ func TestValidateTLSSNINotSane(t *testing.T) {
|
||||||
func TestUpdateValidations(t *testing.T) {
|
func TestUpdateValidations(t *testing.T) {
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
@ -649,13 +649,13 @@ func TestUpdateValidations(t *testing.T) {
|
||||||
func TestCAATimeout(t *testing.T) {
|
func TestCAATimeout(t *testing.T) {
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
va.IssuerDomain = "letsencrypt.org"
|
va.IssuerDomain = "letsencrypt.org"
|
||||||
err := va.checkCAA(core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "caa-timeout.com"}, 101)
|
err := va.checkCAA(core.AcmeIdentifier{Type: core.IdentifierDNS, Value: "caa-timeout.com"}, 101)
|
||||||
if err.Type != probs.ConnectionProblem {
|
if err.Type != probs.ConnectionProblem {
|
||||||
t.Errorf("Expected timeout error type %s, got %s", probs.ConnectionProblem, err.Type)
|
t.Errorf("Expected timeout error type %s, got %s", probs.ConnectionProblem, err.Type)
|
||||||
}
|
}
|
||||||
expected := "DNS query timed out during CAA-record lookup of caa-timeout.com"
|
expected := "DNS problem: query timed out looking up CAA for always.timeout"
|
||||||
if err.Detail != expected {
|
if err.Detail != expected {
|
||||||
t.Errorf("checkCAA: got %#v, expected %#v", err.Detail, expected)
|
t.Errorf("checkCAA: got %#v, expected %#v", err.Detail, expected)
|
||||||
}
|
}
|
||||||
|
|
@ -682,7 +682,7 @@ func TestCAAChecking(t *testing.T) {
|
||||||
|
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
va.IssuerDomain = "letsencrypt.org"
|
va.IssuerDomain = "letsencrypt.org"
|
||||||
for _, caaTest := range tests {
|
for _, caaTest := range tests {
|
||||||
present, valid, err := va.CheckCAARecords(core.AcmeIdentifier{Type: "dns", Value: caaTest.Domain})
|
present, valid, err := va.CheckCAARecords(core.AcmeIdentifier{Type: "dns", Value: caaTest.Domain})
|
||||||
|
|
@ -712,7 +712,7 @@ func TestCAAChecking(t *testing.T) {
|
||||||
func TestDNSValidationFailure(t *testing.T) {
|
func TestDNSValidationFailure(t *testing.T) {
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
@ -749,7 +749,7 @@ func TestDNSValidationInvalid(t *testing.T) {
|
||||||
|
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
@ -763,7 +763,7 @@ func TestDNSValidationInvalid(t *testing.T) {
|
||||||
func TestDNSValidationNotSane(t *testing.T) {
|
func TestDNSValidationNotSane(t *testing.T) {
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
@ -790,7 +790,7 @@ func TestDNSValidationNotSane(t *testing.T) {
|
||||||
func TestDNSValidationServFail(t *testing.T) {
|
func TestDNSValidationServFail(t *testing.T) {
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
@ -839,7 +839,7 @@ func TestDNSValidationNoServer(t *testing.T) {
|
||||||
func TestDNSValidationOK(t *testing.T) {
|
func TestDNSValidationOK(t *testing.T) {
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
@ -873,7 +873,7 @@ func TestDNSValidationOK(t *testing.T) {
|
||||||
func TestDNSValidationLive(t *testing.T) {
|
func TestDNSValidationLive(t *testing.T) {
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
@ -932,7 +932,7 @@ func TestCAAFailure(t *testing.T) {
|
||||||
|
|
||||||
stats, _ := statsd.NewNoopClient()
|
stats, _ := statsd.NewNoopClient()
|
||||||
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, nil, stats, clock.Default())
|
va := NewValidationAuthorityImpl(&PortConfig{TLSPort: port}, nil, stats, clock.Default())
|
||||||
va.DNSResolver = &mocks.DNSResolver{}
|
va.DNSResolver = &bdns.MockDNSResolver{}
|
||||||
mockRA := &MockRegistrationAuthority{}
|
mockRA := &MockRegistrationAuthority{}
|
||||||
va.RA = mockRA
|
va.RA = mockRA
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue