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 }