Update github.com/letsencrypt/challtestsrv to v1.2.0 (#5000)

This pull request updates github.com/letsencrypt/challtestsrv dependency
This commit is contained in:
milgradesec 2020-08-13 19:32:47 +02:00 committed by GitHub
parent a2f29d2c64
commit 20b08365be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 162 additions and 16 deletions

2
go.mod
View File

@ -15,7 +15,7 @@ require (
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/hpcloud/tail v1.0.0
github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548
github.com/letsencrypt/challtestsrv v1.0.2
github.com/letsencrypt/challtestsrv v1.2.0
github.com/letsencrypt/pkcs11key/v4 v4.0.0
github.com/miekg/dns v1.1.30
github.com/miekg/pkcs11 v1.0.3

2
go.sum
View File

@ -119,6 +119,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c=
github.com/letsencrypt/challtestsrv v1.0.2 h1:nBAQjKvVMLhpj4cg2Px6jMyvMbQNdJrCEd6gdcmEuOU=
github.com/letsencrypt/challtestsrv v1.0.2/go.mod h1:/gzSMb+5FjprRIa1TtW6ngjhUOr8JbEFM2XESzK2zPg=
github.com/letsencrypt/challtestsrv v1.2.0 h1:Z/hu1JPFR+cCuI92Hb+LFNxSHG4ARjRYGUipW1S71Vo=
github.com/letsencrypt/challtestsrv v1.2.0/go.mod h1:/gzSMb+5FjprRIa1TtW6ngjhUOr8JbEFM2XESzK2zPg=
github.com/letsencrypt/pkcs11key/v4 v4.0.0 h1:qLc/OznH7xMr5ARJgkZCCWk+EomQkiNTOoOF5LAgagc=
github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=

View File

@ -0,0 +1,22 @@
linters-settings:
gocyclo:
min-complexity: 25
govet:
check-shadowing: false
misspell:
locale: "US"
linters:
enable-all: true
disable:
- stylecheck
- gosec
- dupl
- maligned
- depguard
- lll
- prealloc
- scopelint
- gocritic
- gochecknoinits
- gochecknoglobals

View File

@ -1,14 +1,23 @@
language: go
go:
- "1.11.x"
- "stable"
env:
- GO111MODULE=on
# Override the base install phase so that the project can be installed using
# `-mod=vendor` to use the vendored dependencies
install:
# Install `golangci-lint` using their installer script
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.13.2
# Install `cover` and `goveralls` without `GO111MODULE` enabled so that we
# don't download project dependencies and just put the tools in $GOPATH/bin
- GO111MODULE=off go get golang.org/x/tools/cmd/cover
- GO111MODULE=off go get github.com/mattn/goveralls
- go install -mod=vendor -v -race ./...
script:
- go vet -mod=vendor -v ./...
- go test -mod=vendor -v -race ./...
- set -e
- go mod download
- golangci-lint run
- go test -mod=vendor -v -race -covermode=atomic -coverprofile=coverage.out ./...
- goveralls -coverprofile=coverage.out -service=travis-ci

View File

@ -0,0 +1,3 @@
# Contributor Code of Conduct
The contributor code of conduct is available for reference [on the community forum](https://community.letsencrypt.org/guidelines).

View File

@ -1,9 +1,16 @@
# Challenge Test Server
[![Build Status](https://travis-ci.org/letsencrypt/challtestsrv.svg?branch=master)](https://travis-ci.org/letsencrypt/challtestsrv)
[![Coverage Status](https://coveralls.io/repos/github/letsencrypt/challtestsrv/badge.svg)](https://coveralls.io/github/letsencrypt/challtestsrv)
[![Go Report Card](https://goreportcard.com/badge/github.com/letsencrypt/challtestsrv)](https://goreportcard.com/report/github.com/letsencrypt/challtestsrv)
[![GolangCI](https://golangci.com/badges/github.com/letsencrypt/challtestsrv.svg)](https://golangci.com/r/github.com/letsencrypt/challtestsrv)
The `challtestsrv` package offers a library/command that can be used by test
code to respond to HTTP-01, DNS-01, and TLS-ALPN-01 ACME challenges. The
`challtestsrv` package can also be used as a mock DNS server letting
developers mock `A`, `AAAA`, and `CAA` DNS data for specific hostnames.
developers mock `A`, `AAAA`, `CNAME`, and `CAA` DNS data for specific hostnames.
The mock server will resolve up to one level of `CNAME` aliasing for accepted
DNS request types.
**Important note: The `challtestsrv` command and library are for TEST USAGE
ONLY. It is trivially insecure, offering no authentication. Only use

View File

@ -74,6 +74,10 @@ type mockDNSData struct {
aaaaRecords map[string][]string
// A map of host to CAA policies for CAA responses.
caaRecords map[string][]MockCAAPolicy
// A map of host to CNAME records.
cnameRecords map[string]string
// A map of hostnames that should receive a SERVFAIL response for all queries.
servFailRecords map[string]bool
}
// MockCAAPolicy holds a tag and a value for a CAA record. See
@ -131,11 +135,13 @@ func New(config Config) (*ChallSrv, error) {
tlsALPNOne: make(map[string]string),
redirects: make(map[string]string),
dnsMocks: mockDNSData{
defaultIPv4: defaultIPv4,
defaultIPv6: defaultIPv6,
aRecords: make(map[string][]string),
aaaaRecords: make(map[string][]string),
caaRecords: make(map[string][]MockCAAPolicy),
defaultIPv4: defaultIPv4,
defaultIPv6: defaultIPv6,
aRecords: make(map[string][]string),
aaaaRecords: make(map[string][]string),
caaRecords: make(map[string][]MockCAAPolicy),
cnameRecords: make(map[string]string),
servFailRecords: make(map[string]bool),
},
}

View File

@ -28,6 +28,28 @@ func mockSOA() *dns.SOA {
// more RRs for the response.
type dnsAnswerFunc func(question dns.Question) []dns.RR
// cnameAnswers is a dnsAnswerFunc that creates CNAME RR's for the given question
// using the ChallSrv's dns mock data. If there is no mock CNAME data for the
// given hostname in the question no RR's will be returned.
func (s *ChallSrv) cnameAnswers(q dns.Question) []dns.RR {
var records []dns.RR
if value := s.GetDNSCNAMERecord(q.Name); value != "" {
record := &dns.CNAME{
Hdr: dns.RR_Header{
Name: q.Name,
Rrtype: dns.TypeCNAME,
Class: dns.ClassINET,
},
Target: value,
}
records = append(records, record)
}
return records
}
// txtAnswers is a dnsAnswerFunc that creates TXT RR's for the given question
// using the ChallSrv's dns mock data. If there is no mock TXT data for the
// given hostname in the question no RR's will be returned.
@ -133,8 +155,10 @@ func (s *ChallSrv) caaAnswers(q dns.Question) []dns.RR {
}
// dnsHandler is a miekg/dns handler that can process a dns.Msg request and
// write a response to the provided dns.ResponseWriter. TXT, A, AAAA, and CAA
// queries types are supported and answered using the ChallSrv's mock DNS data.
// write a response to the provided dns.ResponseWriter. TXT, A, AAAA, CNAME,
// and CAA queries types are supported and answered using the ChallSrv's mock
// DNS data. A host that is aliased by a CNAME record will follow that alias
// one level and return the requested record types for that alias' target
func (s *ChallSrv) dnsHandler(w dns.ResponseWriter, r *dns.Msg) {
m := new(dns.Msg)
m.SetReply(r)
@ -146,8 +170,26 @@ func (s *ChallSrv) dnsHandler(w dns.ResponseWriter, r *dns.Msg) {
Question: q,
})
// If there is a ServFail mock set then ignore the question and set the
// SERVFAIL rcode and continue.
if s.GetDNSServFailRecord(q.Name) {
m.SetRcode(r, dns.RcodeServerFailure)
continue
}
// If a CNAME exists for the question include the CNAME record and modify
// the question to instead lookup based on that CNAME's target
if cname := s.GetDNSCNAMERecord(q.Name); cname != "" {
cnameRecords := s.cnameAnswers(q)
m.Answer = append(m.Answer, cnameRecords...)
q = dns.Question{Name: cname, Qtype: q.Qtype}
}
var answerFunc dnsAnswerFunc
switch q.Qtype {
case dns.TypeCNAME:
answerFunc = s.cnameAnswers
case dns.TypeTXT:
answerFunc = s.txtAnswers
case dns.TypeA:

View File

@ -38,6 +38,33 @@ func (s *ChallSrv) GetDefaultDNSIPv6() string {
return s.dnsMocks.defaultIPv6
}
// AddDNSCNAMERecord sets a CNAME record that will be used like an alias when
// querying for other DNS records for the given host.
func (s *ChallSrv) AddDNSCNAMERecord(host string, value string) {
s.challMu.Lock()
defer s.challMu.Unlock()
host = dns.Fqdn(host)
value = dns.Fqdn(value)
s.dnsMocks.cnameRecords[host] = value
}
// GetDNSCNAMERecord returns a target host if a CNAME is set for the querying
// host and an empty string otherwise.
func (s *ChallSrv) GetDNSCNAMERecord(host string) string {
s.challMu.RLock()
host = dns.Fqdn(host)
defer s.challMu.RUnlock()
return s.dnsMocks.cnameRecords[host]
}
// DeleteDNSCAMERecord deletes any CNAME alias set for the given host.
func (s *ChallSrv) DeleteDNSCNAMERecord(host string) {
s.challMu.Lock()
defer s.challMu.Unlock()
host = dns.Fqdn(host)
delete(s.dnsMocks.cnameRecords, host)
}
// AddDNSARecord adds IPv4 addresses that will be returned when querying for
// A records for the given host.
func (s *ChallSrv) AddDNSARecord(host string, addresses []string) {
@ -118,3 +145,30 @@ func (s *ChallSrv) GetDNSCAARecord(host string) []MockCAAPolicy {
host = dns.Fqdn(host)
return s.dnsMocks.caaRecords[host]
}
// AddDNSServFailRecord configures the chall srv to return SERVFAIL responses
// for all queries for the given host.
func (s *ChallSrv) AddDNSServFailRecord(host string) {
s.challMu.Lock()
defer s.challMu.Unlock()
host = dns.Fqdn(host)
s.dnsMocks.servFailRecords[host] = true
}
// DeleteDNSServFailRecord configures the chall srv to no longer return SERVFAIL
// responses for all queries for the given host.
func (s *ChallSrv) DeleteDNSServFailRecord(host string) {
s.challMu.Lock()
defer s.challMu.Unlock()
host = dns.Fqdn(host)
delete(s.dnsMocks.servFailRecords, host)
}
// GetDNSServFailRecord returns true when the chall srv has been configured with
// AddDNSServFailRecord to return SERVFAIL for all queries to the given host.
func (s *ChallSrv) GetDNSServFailRecord(host string) bool {
s.challMu.RLock()
defer s.challMu.RUnlock()
host = dns.Fqdn(host)
return s.dnsMocks.servFailRecords[host]
}

View File

@ -20,9 +20,10 @@ import (
// https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01#section-5.2
const ACMETLS1Protocol = "acme-tls/1"
// As defined in https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-04#section-5.1
// IDPeAcmeIdentifier is the identifier defined in
// https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-04#section-5.1
// id-pe OID + 31 (acmeIdentifier)
var IdPeAcmeIdentifier = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 31}
var IDPeAcmeIdentifier = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 31}
// AddTLSALPNChallenge adds a new TLS-ALPN-01 key authorization for the given host
func (s *ChallSrv) AddTLSALPNChallenge(host, content string) {
@ -75,7 +76,7 @@ func (s *ChallSrv) ServeChallengeCertFunc(k *ecdsa.PrivateKey) func(*tls.ClientH
DNSNames: []string{hello.ServerName},
ExtraExtensions: []pkix.Extension{
{
Id: IdPeAcmeIdentifier,
Id: IDPeAcmeIdentifier,
Critical: true,
Value: extValue,
},

2
vendor/modules.txt vendored
View File

@ -54,7 +54,7 @@ github.com/hpcloud/tail/watch
github.com/hpcloud/tail/winfile
# github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548
github.com/jmhodges/clock
# github.com/letsencrypt/challtestsrv v1.0.2
# github.com/letsencrypt/challtestsrv v1.2.0
github.com/letsencrypt/challtestsrv
# github.com/letsencrypt/pkcs11key/v4 v4.0.0
github.com/letsencrypt/pkcs11key/v4