Store redirects, reconstruct transport on redirect, add redirect + lookup tests
This commit is contained in:
parent
107f171c76
commit
a960fa0393
|
|
@ -251,8 +251,11 @@ type Challenge struct {
|
|||
S string `json:"s,omitempty"`
|
||||
Nonce string `json:"nonce,omitempty"`
|
||||
|
||||
// IP addresses resolved from authorization identifier
|
||||
// IP addresses resolved from authorization identifier during SimpleHTTP validation
|
||||
ResolvedAddrs []net.IP `json:"resolvedAddrs,omitempty"`
|
||||
|
||||
// URLs redirected to during SimpleHTTP validation
|
||||
Redirects []string `json:"redirects,omitempty"`
|
||||
}
|
||||
|
||||
// IsSane checks the sanity of a challenge object before issued to the client
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ func (mock *MockDNS) LookupTXT(hostname string) ([]string, time.Duration, error)
|
|||
|
||||
// LookupHost is a mock
|
||||
func (mock *MockDNS) LookupHost(hostname string) ([]net.IP, time.Duration, time.Duration, error) {
|
||||
if hostname == "always.invalid" {
|
||||
if hostname == "always.invalid" || hostname == "invalid.super" {
|
||||
return []net.IP{}, 0, 0, nil
|
||||
}
|
||||
ip := net.ParseIP("127.0.0.1")
|
||||
|
|
|
|||
|
|
@ -147,17 +147,33 @@ func (va ValidationAuthorityImpl) validateSimpleHTTP(identifier core.AcmeIdentif
|
|||
// selected above.
|
||||
defaultDial := tr.Dial
|
||||
tr.Dial = func(_, _ string) (net.Conn, error) {
|
||||
// Ignore the addr selected by net/http.
|
||||
port := "80"
|
||||
if va.TestMode {
|
||||
port = "5001"
|
||||
} else if scheme == "https" {
|
||||
port = "443"
|
||||
}
|
||||
// Ignore the addr selected by net/http.
|
||||
return defaultDial("tcp", net.JoinHostPort(addrs[0].String(), port))
|
||||
}
|
||||
var redirects []string
|
||||
logRedirect := func(req *http.Request, via []*http.Request) error {
|
||||
redirects = append(redirects, req.URL.String())
|
||||
va.log.Info(fmt.Sprintf("validateSimpleHTTP [%s] redirect from %q to %q", identifier, via[len(via)-1].URL.String(), req.URL.String()))
|
||||
addrs, problem := va.getAddrs(req.URL.Host)
|
||||
if problem != nil {
|
||||
return problem
|
||||
}
|
||||
challenge.ResolvedAddrs = append(challenge.ResolvedAddrs, addrs...)
|
||||
port := "80"
|
||||
if va.TestMode {
|
||||
port = "5001"
|
||||
} else if strings.ToLower(req.URL.Scheme) == "https" {
|
||||
port = "443"
|
||||
}
|
||||
tr.Dial = func(_, _ string) (net.Conn, error) {
|
||||
return defaultDial("tcp", net.JoinHostPort(addrs[0].String(), port))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
client := http.Client{
|
||||
|
|
@ -166,7 +182,7 @@ func (va ValidationAuthorityImpl) validateSimpleHTTP(identifier core.AcmeIdentif
|
|||
Timeout: 5 * time.Second,
|
||||
}
|
||||
httpResponse, err := client.Do(httpRequest)
|
||||
|
||||
challenge.Redirects = redirects
|
||||
if err == nil && httpResponse.StatusCode == 200 {
|
||||
// Read body & test
|
||||
body, readErr := ioutil.ReadAll(httpResponse.Body)
|
||||
|
|
@ -192,9 +208,14 @@ func (va ValidationAuthorityImpl) validateSimpleHTTP(identifier core.AcmeIdentif
|
|||
}
|
||||
} else if err != nil {
|
||||
challenge.Status = core.StatusInvalid
|
||||
challenge.Error = &core.ProblemDetails{
|
||||
Type: parseHTTPConnError(err),
|
||||
Detail: fmt.Sprintf("Could not connect to %s", url.String()),
|
||||
// Catch if error came from CheckRedirect
|
||||
if problem, ok := err.(*core.ProblemDetails); ok {
|
||||
challenge.Error = problem
|
||||
} else {
|
||||
challenge.Error = &core.ProblemDetails{
|
||||
Type: parseHTTPConnError(err),
|
||||
Detail: fmt.Sprintf("Could not connect to %s", url.String()),
|
||||
}
|
||||
}
|
||||
va.log.Debug(strings.Join([]string{challenge.Error.Error(), err.Error()}, ": "))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ const pathWrongToken = "wrongtoken"
|
|||
const path404 = "404"
|
||||
const pathFound = "302"
|
||||
const pathMoved = "301"
|
||||
const pathRedirectLookup = "re-lookup"
|
||||
|
||||
func simpleSrv(t *testing.T, token string, stopChan, waitChan chan bool, enableTLS bool) {
|
||||
m := http.NewServeMux()
|
||||
|
|
@ -85,6 +86,9 @@ func simpleSrv(t *testing.T, token string, stopChan, waitChan chan bool, enableT
|
|||
} else if strings.HasSuffix(r.URL.Path, "wait-long") {
|
||||
t.Logf("SIMPLESRV: Got a wait-long req\n")
|
||||
time.Sleep(time.Second * 10)
|
||||
} else if strings.HasSuffix(r.URL.Path, "re-lookup") {
|
||||
t.Logf("SIMPLESRV: Got a redirect to invalid lookup req\n")
|
||||
http.Redirect(w, r, "http://invalid.super/path", 302)
|
||||
} else {
|
||||
t.Logf("SIMPLESRV: Got a valid req\n")
|
||||
fmt.Fprintf(w, "%s", token)
|
||||
|
|
@ -263,6 +267,7 @@ func TestSimpleHttp(t *testing.T) {
|
|||
test.AssertEquals(t, finChall.Status, core.StatusValid)
|
||||
test.AssertNotError(t, err, chall.Path)
|
||||
test.AssertEquals(t, len(log.GetAllMatching(`redirect from ".*/301" to ".*/valid"`)), 1)
|
||||
test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for localhost: \[127.0.0.1\]`)), 2)
|
||||
|
||||
log.Clear()
|
||||
chall.Path = pathFound
|
||||
|
|
@ -271,6 +276,16 @@ func TestSimpleHttp(t *testing.T) {
|
|||
test.AssertNotError(t, err, chall.Path)
|
||||
test.AssertEquals(t, len(log.GetAllMatching(`redirect from ".*/302" to ".*/301"`)), 1)
|
||||
test.AssertEquals(t, len(log.GetAllMatching(`redirect from ".*/301" to ".*/valid"`)), 1)
|
||||
test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for localhost: \[127.0.0.1\]`)), 3)
|
||||
|
||||
log.Clear()
|
||||
chall.Path = pathRedirectLookup
|
||||
finChall, err = va.validateSimpleHTTP(ident, chall)
|
||||
test.AssertEquals(t, finChall.Status, core.StatusInvalid)
|
||||
test.AssertError(t, err, chall.Path)
|
||||
test.AssertEquals(t, len(log.GetAllMatching(`redirect from ".*/re-lookup" to ".*invalid.super/path"`)), 1)
|
||||
test.AssertEquals(t, len(log.GetAllMatching(`Resolved addresses for localhost: \[127.0.0.1\]`)), 1)
|
||||
test.AssertEquals(t, len(log.GetAllMatching(`Could not resolve invalid.super`)), 1)
|
||||
|
||||
log.Clear()
|
||||
chall.Path = path404
|
||||
|
|
|
|||
Loading…
Reference in New Issue