github.com/letsencrypt/boulder@v0.20251208.0/test/chall-test-srv/mockdns.go (about)

     1  // addDNS01 handles an HTTP POST request to add a new DNS-01 challenge TXT
     2  package main
     3  
     4  import (
     5  	"net/http"
     6  	"strings"
     7  
     8  	"github.com/letsencrypt/challtestsrv"
     9  )
    10  
    11  // setDefaultDNSIPv4 handles an HTTP POST request to set the default IPv4
    12  // address used for all A query responses that do not match more-specific mocked
    13  // responses.
    14  //
    15  // The POST body is expected to have one parameter:
    16  // "ip" - the string representation of an IPv4 address to use for all A queries
    17  // that do not match more specific mocks.
    18  //
    19  // Providing an empty string as the IP value will disable the default
    20  // A responses.
    21  //
    22  // A successful POST will write http.StatusOK to the client.
    23  func (srv *managementServer) setDefaultDNSIPv4(w http.ResponseWriter, r *http.Request) {
    24  	var request struct {
    25  		IP string
    26  	}
    27  	if err := mustParsePOST(&request, r); err != nil {
    28  		http.Error(w, err.Error(), http.StatusBadRequest)
    29  		return
    30  	}
    31  
    32  	// Set the challenge server's default IPv4 address - we allow request.IP to be
    33  	// the empty string so that the default can be cleared using the same
    34  	// method.
    35  	srv.challSrv.SetDefaultDNSIPv4(request.IP)
    36  	srv.log.Printf("Set default IPv4 address for DNS A queries to %q\n", request.IP)
    37  	w.WriteHeader(http.StatusOK)
    38  }
    39  
    40  // setDefaultDNSIPv6 handles an HTTP POST request to set the default IPv6
    41  // address used for all AAAA query responses that do not match more-specific
    42  // mocked responses.
    43  //
    44  // The POST body is expected to have one parameter:
    45  // "ip" - the string representation of an IPv6 address to use for all AAAA
    46  // queries that do not match more specific mocks.
    47  //
    48  // Providing an empty string as the IP value will disable the default
    49  // A responses.
    50  //
    51  // A successful POST will write http.StatusOK to the client.
    52  func (srv *managementServer) setDefaultDNSIPv6(w http.ResponseWriter, r *http.Request) {
    53  	var request struct {
    54  		IP string
    55  	}
    56  	if err := mustParsePOST(&request, r); err != nil {
    57  		http.Error(w, err.Error(), http.StatusBadRequest)
    58  		return
    59  	}
    60  
    61  	// Set the challenge server's default IPv6 address - we allow request.IP to be
    62  	// the empty string so that the default can be cleared using the same
    63  	// method.
    64  	srv.challSrv.SetDefaultDNSIPv6(request.IP)
    65  	srv.log.Printf("Set default IPv6 address for DNS AAAA queries to %q\n", request.IP)
    66  	w.WriteHeader(http.StatusOK)
    67  }
    68  
    69  // addDNSARecord handles an HTTP POST request to add a mock A query response record
    70  // for a host.
    71  //
    72  // The POST body is expected to have two non-empty parameters:
    73  // "host" - the hostname that when queried should return the mocked A record.
    74  // "addresses" - an array of IPv4 addresses in string representation that should
    75  // be used for the A records returned for the query.
    76  //
    77  // A successful POST will write http.StatusOK to the client.
    78  func (srv *managementServer) addDNSARecord(w http.ResponseWriter, r *http.Request) {
    79  	var request struct {
    80  		Host      string
    81  		Addresses []string
    82  	}
    83  	if err := mustParsePOST(&request, r); err != nil {
    84  		http.Error(w, err.Error(), http.StatusBadRequest)
    85  		return
    86  	}
    87  
    88  	// If the request has no addresses or an empty host it's a bad request
    89  	if len(request.Addresses) == 0 || request.Host == "" {
    90  		w.WriteHeader(http.StatusBadRequest)
    91  		return
    92  	}
    93  
    94  	srv.challSrv.AddDNSARecord(request.Host, request.Addresses)
    95  	srv.log.Printf("Added response for DNS A queries to %q : %s\n",
    96  		request.Host, strings.Join(request.Addresses, ", "))
    97  	w.WriteHeader(http.StatusOK)
    98  }
    99  
   100  // delDNSARecord handles an HTTP POST request to delete an existing mock A
   101  // policy record for a host.
   102  //
   103  // The POST body is expected to have one non-empty parameter:
   104  // "host" - the hostname to remove the mock A record for.
   105  //
   106  // A successful POST will write http.StatusOK to the client.
   107  func (srv *managementServer) delDNSARecord(w http.ResponseWriter, r *http.Request) {
   108  	var request struct {
   109  		Host string
   110  	}
   111  	if err := mustParsePOST(&request, r); err != nil {
   112  		http.Error(w, err.Error(), http.StatusBadRequest)
   113  		return
   114  	}
   115  
   116  	// If the request has an empty host it's a bad request
   117  	if request.Host == "" {
   118  		w.WriteHeader(http.StatusBadRequest)
   119  		return
   120  	}
   121  
   122  	srv.challSrv.DeleteDNSARecord(request.Host)
   123  	srv.log.Printf("Removed response for DNS A queries to %q", request.Host)
   124  	w.WriteHeader(http.StatusOK)
   125  }
   126  
   127  // addDNSAAAARecord handles an HTTP POST request to add a mock AAAA query
   128  // response record for a host.
   129  //
   130  // The POST body is expected to have two non-empty parameters:
   131  // "host" - the hostname that when queried should return the mocked A record.
   132  // "addresses" - an array of IPv6 addresses in string representation that should
   133  // be used for the AAAA records returned for the query.
   134  //
   135  // A successful POST will write http.StatusOK to the client.
   136  func (srv *managementServer) addDNSAAAARecord(w http.ResponseWriter, r *http.Request) {
   137  	var request struct {
   138  		Host      string
   139  		Addresses []string
   140  	}
   141  	if err := mustParsePOST(&request, r); err != nil {
   142  		http.Error(w, err.Error(), http.StatusBadRequest)
   143  		return
   144  	}
   145  
   146  	// If the request has no addresses or an empty host it's a bad request
   147  	if len(request.Addresses) == 0 || request.Host == "" {
   148  		w.WriteHeader(http.StatusBadRequest)
   149  		return
   150  	}
   151  
   152  	srv.challSrv.AddDNSAAAARecord(request.Host, request.Addresses)
   153  	srv.log.Printf("Added response for DNS AAAA queries to %q : %s\n",
   154  		request.Host, strings.Join(request.Addresses, ", "))
   155  	w.WriteHeader(http.StatusOK)
   156  }
   157  
   158  // delDNSAAAARecord handles an HTTP POST request to delete an existing mock AAAA
   159  // policy record for a host.
   160  //
   161  // The POST body is expected to have one non-empty parameter:
   162  // "host" - the hostname to remove the mock AAAA record for.
   163  //
   164  // A successful POST will write http.StatusOK to the client.
   165  func (srv *managementServer) delDNSAAAARecord(w http.ResponseWriter, r *http.Request) {
   166  	var request struct {
   167  		Host string
   168  	}
   169  	if err := mustParsePOST(&request, r); err != nil {
   170  		http.Error(w, err.Error(), http.StatusBadRequest)
   171  		return
   172  	}
   173  
   174  	// If the request has an empty host it's a bad request
   175  	if request.Host == "" {
   176  		w.WriteHeader(http.StatusBadRequest)
   177  		return
   178  	}
   179  
   180  	srv.challSrv.DeleteDNSAAAARecord(request.Host)
   181  	srv.log.Printf("Removed response for DNS AAAA queries to %q", request.Host)
   182  	w.WriteHeader(http.StatusOK)
   183  }
   184  
   185  // addDNSCAARecord handles an HTTP POST request to add a mock CAA query
   186  // response record for a host.
   187  //
   188  // The POST body is expected to have two non-empty parameters:
   189  // "host" - the hostname that when queried should return the mocked CAA record.
   190  // "policies" - an array of CAA policy objects. Each policy object is expected
   191  // to have two non-empty keys, "tag" and "value".
   192  //
   193  // A successful POST will write http.StatusOK to the client.
   194  func (srv *managementServer) addDNSCAARecord(w http.ResponseWriter, r *http.Request) {
   195  	var request struct {
   196  		Host     string
   197  		Policies []challtestsrv.MockCAAPolicy
   198  	}
   199  	if err := mustParsePOST(&request, r); err != nil {
   200  		http.Error(w, err.Error(), http.StatusBadRequest)
   201  		return
   202  	}
   203  
   204  	// If the request has no host or no caa policies it's a bad request
   205  	if request.Host == "" || len(request.Policies) == 0 {
   206  		w.WriteHeader(http.StatusBadRequest)
   207  		return
   208  	}
   209  
   210  	srv.challSrv.AddDNSCAARecord(request.Host, request.Policies)
   211  	srv.log.Printf("Added response for DNS CAA queries to %q", request.Host)
   212  	w.WriteHeader(http.StatusOK)
   213  }
   214  
   215  // delDNSCAARecord handles an HTTP POST request to delete an existing mock CAA
   216  // policy record for a host.
   217  //
   218  // The POST body is expected to have one non-empty parameter:
   219  // "host" - the hostname to remove the mock CAA policy for.
   220  //
   221  // A successful POST will write http.StatusOK to the client.
   222  func (srv *managementServer) delDNSCAARecord(w http.ResponseWriter, r *http.Request) {
   223  	var request struct {
   224  		Host string
   225  	}
   226  	if err := mustParsePOST(&request, r); err != nil {
   227  		http.Error(w, err.Error(), http.StatusBadRequest)
   228  		return
   229  	}
   230  
   231  	// If the request has an empty host it's a bad request
   232  	if request.Host == "" {
   233  		w.WriteHeader(http.StatusBadRequest)
   234  		return
   235  	}
   236  
   237  	srv.challSrv.DeleteDNSCAARecord(request.Host)
   238  	srv.log.Printf("Removed response for DNS CAA queries to %q", request.Host)
   239  	w.WriteHeader(http.StatusOK)
   240  }
   241  
   242  // addDNSCNAMERecord handles an HTTP POST request to add a mock CNAME query
   243  // response record and alias for a host.
   244  //
   245  // The POST body is expected to have two non-empty parameters:
   246  // "host" - the hostname that should be treated as an alias to the target
   247  // "target" - the hostname whose mocked DNS records should be returned
   248  //
   249  // A successful POST will write http.StatusOK to the client.
   250  func (srv *managementServer) addDNSCNAMERecord(w http.ResponseWriter, r *http.Request) {
   251  	var request struct {
   252  		Host   string
   253  		Target string
   254  	}
   255  	if err := mustParsePOST(&request, r); err != nil {
   256  		http.Error(w, err.Error(), http.StatusBadRequest)
   257  		return
   258  	}
   259  
   260  	// If the request has no host or no caa policies it's a bad request
   261  	if request.Host == "" || request.Target == "" {
   262  		w.WriteHeader(http.StatusBadRequest)
   263  		return
   264  	}
   265  
   266  	srv.challSrv.AddDNSCNAMERecord(request.Host, request.Target)
   267  	srv.log.Printf("Added response for DNS CNAME queries to %q targeting %q", request.Host, request.Target)
   268  	w.WriteHeader(http.StatusOK)
   269  }
   270  
   271  // delDNSCNAMERecord handles an HTTP POST request to delete an existing mock
   272  // CNAME record for a host.
   273  //
   274  // The POST body is expected to have one non-empty parameters:
   275  // "host" - the hostname to remove the mock CNAME alias for.
   276  //
   277  // A successful POST will write http.StatusOK to the client.
   278  func (srv *managementServer) delDNSCNAMERecord(w http.ResponseWriter, r *http.Request) {
   279  	var request struct {
   280  		Host string
   281  	}
   282  	if err := mustParsePOST(&request, r); err != nil {
   283  		http.Error(w, err.Error(), http.StatusBadRequest)
   284  		return
   285  	}
   286  
   287  	// If the request has an empty host it's a bad request
   288  	if request.Host == "" {
   289  		w.WriteHeader(http.StatusBadRequest)
   290  		return
   291  	}
   292  
   293  	srv.challSrv.DeleteDNSCNAMERecord(request.Host)
   294  	srv.log.Printf("Removed response for DNS CNAME queries to %q", request.Host)
   295  	w.WriteHeader(http.StatusOK)
   296  }
   297  
   298  // addDNSServFailRecord handles an HTTP POST request to add a mock SERVFAIL
   299  // response record for a host. All queries for that host will subsequently
   300  // result in SERVFAIL responses, overriding any other mocks.
   301  //
   302  // The POST body is expected to have one non-empty parameter:
   303  // "host" - the hostname that should return SERVFAIL responses.
   304  //
   305  // A successful POST will write http.StatusOK to the client.
   306  func (srv *managementServer) addDNSServFailRecord(w http.ResponseWriter, r *http.Request) {
   307  	var request struct {
   308  		Host string
   309  	}
   310  	if err := mustParsePOST(&request, r); err != nil {
   311  		http.Error(w, err.Error(), http.StatusBadRequest)
   312  		return
   313  	}
   314  
   315  	// If the request has no host it's a bad request
   316  	if request.Host == "" {
   317  		w.WriteHeader(http.StatusBadRequest)
   318  		return
   319  	}
   320  
   321  	srv.challSrv.AddDNSServFailRecord(request.Host)
   322  	srv.log.Printf("Added SERVFAIL response for DNS queries to %q", request.Host)
   323  	w.WriteHeader(http.StatusOK)
   324  }
   325  
   326  // delDNSServFailRecord handles an HTTP POST request to delete an existing mock
   327  // SERVFAIL record for a host.
   328  //
   329  // The POST body is expected to have one non-empty parameters:
   330  // "host" - the hostname to remove the mock SERVFAIL response from.
   331  //
   332  // A successful POST will write http.StatusOK to the client.
   333  func (srv *managementServer) delDNSServFailRecord(w http.ResponseWriter, r *http.Request) {
   334  	var request struct {
   335  		Host string
   336  	}
   337  	if err := mustParsePOST(&request, r); err != nil {
   338  		http.Error(w, err.Error(), http.StatusBadRequest)
   339  		return
   340  	}
   341  
   342  	// If the request has an empty host it's a bad request
   343  	if request.Host == "" {
   344  		w.WriteHeader(http.StatusBadRequest)
   345  		return
   346  	}
   347  
   348  	srv.challSrv.DeleteDNSServFailRecord(request.Host)
   349  	srv.log.Printf("Removed SERVFAIL response for DNS queries to %q", request.Host)
   350  	w.WriteHeader(http.StatusOK)
   351  }