1 package va
2
3 import (
4 "context"
5 "fmt"
6 "net"
7 "strings"
8 "testing"
9 "time"
10
11 "github.com/jmhodges/clock"
12 "github.com/letsencrypt/boulder/bdns"
13 "github.com/letsencrypt/boulder/core"
14 "github.com/letsencrypt/boulder/identifier"
15 "github.com/letsencrypt/boulder/metrics"
16 "github.com/letsencrypt/boulder/probs"
17 "github.com/letsencrypt/boulder/test"
18 "github.com/prometheus/client_golang/prometheus"
19 )
20
21 func dnsChallenge() core.Challenge {
22 return createChallenge(core.ChallengeTypeDNS01)
23 }
24
25 func TestDNSValidationEmpty(t *testing.T) {
26 va, _ := setup(nil, 0, "", nil)
27
28
29
30 req := createValidationRequest("empty-txts.com", core.ChallengeTypeDNS01)
31 res, _ := va.PerformValidation(context.Background(), req)
32 test.AssertEquals(t, res.Problems.ProblemType, "unauthorized")
33 test.AssertEquals(t, res.Problems.Detail, "No TXT record found at _acme-challenge.empty-txts.com")
34
35 test.AssertMetricWithLabelsEquals(t, va.metrics.validationTime, prometheus.Labels{
36 "type": "dns-01",
37 "result": "invalid",
38 "problem_type": "unauthorized",
39 }, 1)
40 }
41
42 func TestDNSValidationWrong(t *testing.T) {
43 va, _ := setup(nil, 0, "", nil)
44
45 _, prob := va.validateDNS01(context.Background(), dnsi("wrong-dns01.com"), dnsChallenge())
46 if prob == nil {
47 t.Fatalf("Successful DNS validation with wrong TXT record")
48 }
49 test.AssertEquals(t, prob.Error(), "unauthorized :: Incorrect TXT record \"a\" found at _acme-challenge.wrong-dns01.com")
50 }
51
52 func TestDNSValidationWrongMany(t *testing.T) {
53 va, _ := setup(nil, 0, "", nil)
54
55 _, prob := va.validateDNS01(context.Background(), dnsi("wrong-many-dns01.com"), dnsChallenge())
56 if prob == nil {
57 t.Fatalf("Successful DNS validation with wrong TXT record")
58 }
59 test.AssertEquals(t, prob.Error(), "unauthorized :: Incorrect TXT record \"a\" (and 4 more) found at _acme-challenge.wrong-many-dns01.com")
60 }
61
62 func TestDNSValidationWrongLong(t *testing.T) {
63 va, _ := setup(nil, 0, "", nil)
64
65 _, prob := va.validateDNS01(context.Background(), dnsi("long-dns01.com"), dnsChallenge())
66 if prob == nil {
67 t.Fatalf("Successful DNS validation with wrong TXT record")
68 }
69 test.AssertEquals(t, prob.Error(), "unauthorized :: Incorrect TXT record \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...\" found at _acme-challenge.long-dns01.com")
70 }
71
72 func TestDNSValidationFailure(t *testing.T) {
73 va, _ := setup(nil, 0, "", nil)
74
75 _, prob := va.validateDNS01(ctx, dnsi("localhost"), dnsChallenge())
76
77 test.AssertEquals(t, prob.Type, probs.UnauthorizedProblem)
78 }
79
80 func TestDNSValidationInvalid(t *testing.T) {
81 var notDNS = identifier.ACMEIdentifier{
82 Type: identifier.IdentifierType("iris"),
83 Value: "790DB180-A274-47A4-855F-31C428CB1072",
84 }
85
86 va, _ := setup(nil, 0, "", nil)
87
88 _, prob := va.validateDNS01(ctx, notDNS, dnsChallenge())
89
90 test.AssertEquals(t, prob.Type, probs.MalformedProblem)
91 }
92
93 func TestDNSValidationNotSane(t *testing.T) {
94 va, _ := setup(nil, 0, "", nil)
95
96 chall := dnsChallenge()
97 chall.Token = ""
98 _, prob := va.validateChallenge(ctx, dnsi("localhost"), chall)
99 if prob.Type != probs.MalformedProblem {
100 t.Errorf("Got wrong error type: expected %s, got %s",
101 prob.Type, probs.MalformedProblem)
102 }
103 if !strings.Contains(prob.Error(), "Challenge failed consistency check:") {
104 t.Errorf("Got wrong error: %s", prob.Error())
105 }
106
107 chall.Token = "yfCBb-bRTLz8Wd1C0lTUQK3qlKj3-t2tYGwx5Hj7r_"
108 _, prob = va.validateChallenge(ctx, dnsi("localhost"), chall)
109 if prob.Type != probs.MalformedProblem {
110 t.Errorf("Got wrong error type: expected %s, got %s",
111 prob.Type, probs.MalformedProblem)
112 }
113 if !strings.Contains(prob.Error(), "Challenge failed consistency check:") {
114 t.Errorf("Got wrong error: %s", prob.Error())
115 }
116
117 chall.ProvidedKeyAuthorization = "a"
118 _, prob = va.validateChallenge(ctx, dnsi("localhost"), chall)
119 if prob.Type != probs.MalformedProblem {
120 t.Errorf("Got wrong error type: expected %s, got %s",
121 prob.Type, probs.MalformedProblem)
122 }
123 if !strings.Contains(prob.Error(), "Challenge failed consistency check:") {
124 t.Errorf("Got wrong error: %s", prob.Error())
125 }
126
127 }
128
129 func TestDNSValidationServFail(t *testing.T) {
130 va, _ := setup(nil, 0, "", nil)
131
132 _, prob := va.validateChallenge(ctx, dnsi("servfail.com"), dnsChallenge())
133
134 test.AssertEquals(t, prob.Type, probs.DNSProblem)
135 }
136
137 func TestDNSValidationNoServer(t *testing.T) {
138 va, log := setup(nil, 0, "", nil)
139 staticProvider, err := bdns.NewStaticProvider([]string{})
140 test.AssertNotError(t, err, "Couldn't make new static provider")
141
142 va.dnsClient = bdns.NewTest(
143 time.Second*5,
144 staticProvider,
145 metrics.NoopRegisterer,
146 clock.New(),
147 1,
148 log)
149
150 _, prob := va.validateChallenge(ctx, dnsi("localhost"), dnsChallenge())
151
152 test.AssertEquals(t, prob.Type, probs.DNSProblem)
153 }
154
155 func TestDNSValidationOK(t *testing.T) {
156 va, _ := setup(nil, 0, "", nil)
157
158 _, prob := va.validateChallenge(ctx, dnsi("good-dns01.com"), dnsChallenge())
159
160 test.Assert(t, prob == nil, "Should be valid.")
161 }
162
163 func TestDNSValidationNoAuthorityOK(t *testing.T) {
164 va, _ := setup(nil, 0, "", nil)
165
166 _, prob := va.validateChallenge(ctx, dnsi("no-authority-dns01.com"), dnsChallenge())
167
168 test.Assert(t, prob == nil, "Should be valid.")
169 }
170
171 func TestAvailableAddresses(t *testing.T) {
172 v6a := net.ParseIP("::1")
173 v6b := net.ParseIP("2001:db8::2:1")
174 v4a := net.ParseIP("127.0.0.1")
175 v4b := net.ParseIP("192.0.2.1")
176
177 testcases := []struct {
178 input []net.IP
179 v4 []net.IP
180 v6 []net.IP
181 }{
182
183 {
184 []net.IP{},
185 []net.IP{},
186 []net.IP{},
187 },
188
189 {
190 []net.IP{v4a},
191 []net.IP{v4a},
192 []net.IP{},
193 },
194
195 {
196 []net.IP{v4a, v6a},
197 []net.IP{v4a},
198 []net.IP{v6a},
199 },
200
201 {
202 []net.IP{v6a, v4a},
203 []net.IP{v4a},
204 []net.IP{v6a},
205 },
206
207 {
208 []net.IP{v6a, v6b},
209 []net.IP{},
210 []net.IP{v6a, v6b},
211 },
212
213 {
214 []net.IP{v6a, v4a, v6b, v4b},
215 []net.IP{v4a, v4b},
216 []net.IP{v6a, v6b},
217 },
218 }
219
220 for _, tc := range testcases {
221
222 v4result, v6result := availableAddresses(tc.input)
223
224
225 test.Assert(t, len(tc.v4) == len(v4result),
226 fmt.Sprintf("Wrong # of IPv4 results: expected %d, got %d", len(tc.v4), len(v4result)))
227
228
229 for i, v4addr := range tc.v4 {
230 test.Assert(t, v4addr.String() == v4result[i].String(),
231 fmt.Sprintf("Wrong v4 result index %d: expected %q got %q", i, v4addr.String(), v4result[i].String()))
232 }
233
234
235 test.Assert(t, len(tc.v6) == len(v6result),
236 fmt.Sprintf("Wrong # of IPv6 results: expected %d, got %d", len(tc.v6), len(v6result)))
237
238
239 for i, v6addr := range tc.v6 {
240 test.Assert(t, v6addr.String() == v6result[i].String(),
241 fmt.Sprintf("Wrong v6 result index %d: expected %q got %q", i, v6addr.String(), v6result[i].String()))
242 }
243 }
244 }
245
View as plain text