boulder/test/chall-test-srv/mockdns.go

352 lines
12 KiB
Go

// addDNS01 handles an HTTP POST request to add a new DNS-01 challenge TXT
package main
import (
"net/http"
"strings"
"github.com/letsencrypt/challtestsrv"
)
// setDefaultDNSIPv4 handles an HTTP POST request to set the default IPv4
// address used for all A query responses that do not match more-specific mocked
// responses.
//
// The POST body is expected to have one parameter:
// "ip" - the string representation of an IPv4 address to use for all A queries
// that do not match more specific mocks.
//
// Providing an empty string as the IP value will disable the default
// A responses.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) setDefaultDNSIPv4(w http.ResponseWriter, r *http.Request) {
var request struct {
IP string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Set the challenge server's default IPv4 address - we allow request.IP to be
// the empty string so that the default can be cleared using the same
// method.
srv.challSrv.SetDefaultDNSIPv4(request.IP)
srv.log.Printf("Set default IPv4 address for DNS A queries to %q\n", request.IP)
w.WriteHeader(http.StatusOK)
}
// setDefaultDNSIPv6 handles an HTTP POST request to set the default IPv6
// address used for all AAAA query responses that do not match more-specific
// mocked responses.
//
// The POST body is expected to have one parameter:
// "ip" - the string representation of an IPv6 address to use for all AAAA
// queries that do not match more specific mocks.
//
// Providing an empty string as the IP value will disable the default
// A responses.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) setDefaultDNSIPv6(w http.ResponseWriter, r *http.Request) {
var request struct {
IP string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Set the challenge server's default IPv6 address - we allow request.IP to be
// the empty string so that the default can be cleared using the same
// method.
srv.challSrv.SetDefaultDNSIPv6(request.IP)
srv.log.Printf("Set default IPv6 address for DNS AAAA queries to %q\n", request.IP)
w.WriteHeader(http.StatusOK)
}
// addDNSARecord handles an HTTP POST request to add a mock A query response record
// for a host.
//
// The POST body is expected to have two non-empty parameters:
// "host" - the hostname that when queried should return the mocked A record.
// "addresses" - an array of IPv4 addresses in string representation that should
// be used for the A records returned for the query.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) addDNSARecord(w http.ResponseWriter, r *http.Request) {
var request struct {
Host string
Addresses []string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// If the request has no addresses or an empty host it's a bad request
if len(request.Addresses) == 0 || request.Host == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
srv.challSrv.AddDNSARecord(request.Host, request.Addresses)
srv.log.Printf("Added response for DNS A queries to %q : %s\n",
request.Host, strings.Join(request.Addresses, ", "))
w.WriteHeader(http.StatusOK)
}
// delDNSARecord handles an HTTP POST request to delete an existing mock A
// policy record for a host.
//
// The POST body is expected to have one non-empty parameter:
// "host" - the hostname to remove the mock A record for.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) delDNSARecord(w http.ResponseWriter, r *http.Request) {
var request struct {
Host string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// If the request has an empty host it's a bad request
if request.Host == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
srv.challSrv.DeleteDNSARecord(request.Host)
srv.log.Printf("Removed response for DNS A queries to %q", request.Host)
w.WriteHeader(http.StatusOK)
}
// addDNSAAAARecord handles an HTTP POST request to add a mock AAAA query
// response record for a host.
//
// The POST body is expected to have two non-empty parameters:
// "host" - the hostname that when queried should return the mocked A record.
// "addresses" - an array of IPv6 addresses in string representation that should
// be used for the AAAA records returned for the query.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) addDNSAAAARecord(w http.ResponseWriter, r *http.Request) {
var request struct {
Host string
Addresses []string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// If the request has no addresses or an empty host it's a bad request
if len(request.Addresses) == 0 || request.Host == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
srv.challSrv.AddDNSAAAARecord(request.Host, request.Addresses)
srv.log.Printf("Added response for DNS AAAA queries to %q : %s\n",
request.Host, strings.Join(request.Addresses, ", "))
w.WriteHeader(http.StatusOK)
}
// delDNSAAAARecord handles an HTTP POST request to delete an existing mock AAAA
// policy record for a host.
//
// The POST body is expected to have one non-empty parameter:
// "host" - the hostname to remove the mock AAAA record for.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) delDNSAAAARecord(w http.ResponseWriter, r *http.Request) {
var request struct {
Host string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// If the request has an empty host it's a bad request
if request.Host == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
srv.challSrv.DeleteDNSAAAARecord(request.Host)
srv.log.Printf("Removed response for DNS AAAA queries to %q", request.Host)
w.WriteHeader(http.StatusOK)
}
// addDNSCAARecord handles an HTTP POST request to add a mock CAA query
// response record for a host.
//
// The POST body is expected to have two non-empty parameters:
// "host" - the hostname that when queried should return the mocked CAA record.
// "policies" - an array of CAA policy objects. Each policy object is expected
// to have two non-empty keys, "tag" and "value".
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) addDNSCAARecord(w http.ResponseWriter, r *http.Request) {
var request struct {
Host string
Policies []challtestsrv.MockCAAPolicy
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// If the request has no host or no caa policies it's a bad request
if request.Host == "" || len(request.Policies) == 0 {
w.WriteHeader(http.StatusBadRequest)
return
}
srv.challSrv.AddDNSCAARecord(request.Host, request.Policies)
srv.log.Printf("Added response for DNS CAA queries to %q", request.Host)
w.WriteHeader(http.StatusOK)
}
// delDNSCAARecord handles an HTTP POST request to delete an existing mock CAA
// policy record for a host.
//
// The POST body is expected to have one non-empty parameter:
// "host" - the hostname to remove the mock CAA policy for.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) delDNSCAARecord(w http.ResponseWriter, r *http.Request) {
var request struct {
Host string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// If the request has an empty host it's a bad request
if request.Host == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
srv.challSrv.DeleteDNSCAARecord(request.Host)
srv.log.Printf("Removed response for DNS CAA queries to %q", request.Host)
w.WriteHeader(http.StatusOK)
}
// addDNSCNAMERecord handles an HTTP POST request to add a mock CNAME query
// response record and alias for a host.
//
// The POST body is expected to have two non-empty parameters:
// "host" - the hostname that should be treated as an alias to the target
// "target" - the hostname whose mocked DNS records should be returned
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) addDNSCNAMERecord(w http.ResponseWriter, r *http.Request) {
var request struct {
Host string
Target string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// If the request has no host or no caa policies it's a bad request
if request.Host == "" || request.Target == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
srv.challSrv.AddDNSCNAMERecord(request.Host, request.Target)
srv.log.Printf("Added response for DNS CNAME queries to %q targeting %q", request.Host, request.Target)
w.WriteHeader(http.StatusOK)
}
// delDNSCNAMERecord handles an HTTP POST request to delete an existing mock
// CNAME record for a host.
//
// The POST body is expected to have one non-empty parameters:
// "host" - the hostname to remove the mock CNAME alias for.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) delDNSCNAMERecord(w http.ResponseWriter, r *http.Request) {
var request struct {
Host string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// If the request has an empty host it's a bad request
if request.Host == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
srv.challSrv.DeleteDNSCNAMERecord(request.Host)
srv.log.Printf("Removed response for DNS CNAME queries to %q", request.Host)
w.WriteHeader(http.StatusOK)
}
// addDNSServFailRecord handles an HTTP POST request to add a mock SERVFAIL
// response record for a host. All queries for that host will subsequently
// result in SERVFAIL responses, overriding any other mocks.
//
// The POST body is expected to have one non-empty parameter:
// "host" - the hostname that should return SERVFAIL responses.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) addDNSServFailRecord(w http.ResponseWriter, r *http.Request) {
var request struct {
Host string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// If the request has no host it's a bad request
if request.Host == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
srv.challSrv.AddDNSServFailRecord(request.Host)
srv.log.Printf("Added SERVFAIL response for DNS queries to %q", request.Host)
w.WriteHeader(http.StatusOK)
}
// delDNSServFailRecord handles an HTTP POST request to delete an existing mock
// SERVFAIL record for a host.
//
// The POST body is expected to have one non-empty parameters:
// "host" - the hostname to remove the mock SERVFAIL response from.
//
// A successful POST will write http.StatusOK to the client.
func (srv *managementServer) delDNSServFailRecord(w http.ResponseWriter, r *http.Request) {
var request struct {
Host string
}
if err := mustParsePOST(&request, r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// If the request has an empty host it's a bad request
if request.Host == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
srv.challSrv.DeleteDNSServFailRecord(request.Host)
srv.log.Printf("Removed SERVFAIL response for DNS queries to %q", request.Host)
w.WriteHeader(http.StatusOK)
}